Skip to content

Fix import purge on cleaner failure and reclaim leftover local CSV disk - #6547

Open
EmmS21 wants to merge 5 commits into
plausible:masterfrom
EmmS21:fix/oban-import-cleaner-side-effects
Open

Fix import purge on cleaner failure and reclaim leftover local CSV disk#6547
EmmS21 wants to merge 5 commits into
plausible:masterfrom
EmmS21:fix/oban-import-cleaner-side-effects

Conversation

@EmmS21

@EmmS21 EmmS21 commented Jul 26, 2026

Copy link
Copy Markdown

Summary

Fixes #6515: when LocalImportAnalyticsCleaner crashed (often File.rm! → permission denied on self-hosted volumes), ObanErrorReporter treated that like an ImportAnalytics failure and purged already-imported ClickHouse stats.

  1. Fix the product bug — Scope import_fail / import_fail_transient to Plausible.Workers.ImportAnalytics only. Cleanup crashes must not undo a completed import. I considered a separate queue for the cleaner; matching on worker fixes the misclassification with less churn.
  2. Log stuck cleanup — On the cleaner’s final attempt, log path + import_id when delete still fails (ops/debug signal, not user email).

Leftover local CSV disk / volume ownership on CE images is a separate follow-up and belongs in Discussions as an image/ops change, not this bugfix.

Test plan

  • mix test test/workers/oban_error_reporter_test.exs test/workers/local_import_analytics_cleaner_test.exs
  • Confirm ImportAnalytics exceptions still purge / mark failed / email as before
  • Confirm LocalImportAnalyticsCleaner exceptions do not purge stats or mark the import failed
  • Local cleaner: deletes when import completed; snoozes while importing; logs only on final undeleteable attempt

EmmS21 and others added 3 commits July 26, 2026 13:01
A finished CSV import can still leave a LocalImportAnalyticsCleaner job on
analytics_imports with the same import_id. The error reporter used to match
on queue + import_id only, so a cleaner crash (for example permission denied
deleting leftover files) purged ClickHouse stats and could eventually mark
the import failed. Scope import_fail / import_fail_transient to the import
worker so cleanup failures cannot undo a completed import.

I considered giving the cleaner its own queue. That was never debated when
the cleaner was added, and it would not make undeletable files deletable.
Matching on worker fixes the misclassification without new queue config or
changing forget-import cancellation.

Co-authored-by: Cursor <cursoragent@cursor.com>
After import-failure side effects are scoped away from the cleaner, a stuck
File.rm still leaves CSVs on disk. On the final Oban attempt, log the path
and import_id so operators can see cleanup gave up.

I did not add UI or user email for this. Import/export mail in this codebase
covers the outcome of loading or producing data; other janitor workers use
logs. Leftover file delete is the same class of work.

Co-authored-by: Cursor <cursoragent@cursor.com>
Fixing the error reporter stops cleanup crashes from wiping imported stats,
but leftover CSVs can still sit on self-hosted disk when the volume is owned
by the wrong user and File.rm is denied. Elixir cannot override that OS
refusal.

When the entrypoint starts as root, chown DATA_DIR to the plausible user,
then su-exec down before starting the app so typical Compose upgrades can
clear leftovers without teaching Docker UIDs. Non-root starts are unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
@CLAassistant

CLAassistant commented Jul 26, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@EmmS21

EmmS21 commented Jul 27, 2026

Copy link
Copy Markdown
Author

Further discussion:
#6548

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ObanErrorReporter purges imported data when the cleanup worker crashes — silent loss of completed CSV imports

2 participants