Conversation
Run sentry-cleanup on sentry-self-hosted-local with cron/run_daily.py, which runs sentry cleanup every day at midnight like the old '0 0 * * *' crontab. This drops the separate image that installed cron and gosu with apt-get and its bash entrypoint, so sentry-cleanup also works on a sentry image without a shell.
Coverage Results 📊✅ 22 passed | Total: 22 | Pass Rate: 100% | Execution Time: 9m 50s 📊 Comparison with Base Branch
✨ Test counts unchanged from base. All tests are passing successfully. ✅ Patch coverage is 100.00% (no changed executable lines found; target 50%). Coverage diff@@ Coverage Diff @@
## master #4544 +/-##
==========================================
Coverage 95.54% 95.54% —%
==========================================
Files 5 5 —
Tracked lines 336 336 —
Branches 0 0 —
==========================================
Hits 321 321 —
Misses 15 15 —
Partials 0 0 —Generated by Coverage Action |
BYK
left a comment
There was a problem hiding this comment.
If this works, I'm game! I hated that extra cron image from the beginning!
…duled run sentry cleanup has no lock and can hang (e.g. its JoinableQueue.join() never returns if a worker is killed mid-task). Run each cleanup in its own process group and stop it (SIGTERM, then SIGKILL) if it's still running at the next midnight, so a stuck run can't block the schedule and runs never overlap. Forward SIGTERM to the run on container stop. Also remove the obsolete sentry-cleanup-self-hosted-local image during install.
|
|
||
|
|
||
| def stop(proc: subprocess.Popen[bytes]) -> None: | ||
| # The run is its own process group, so this also reaches its workers. |
There was a problem hiding this comment.
Bug: An unhandled ProcessLookupError can crash the script due to a race condition where a subprocess exits before os.killpg() is called.
Severity: MEDIUM
Suggested Fix
Wrap the os.killpg() calls in a try...except ProcessLookupError block to gracefully handle cases where the process has already exited, preventing the script from crashing.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: cron/run_daily.py#L31
Potential issue: A race condition can occur if the subprocess exits between the
`current.poll() is None` check and the subsequent call to `os.killpg()`. If the process
group no longer exists when `os.killpg()` is called, it will raise a
`ProcessLookupError`. This exception is not handled within a `try...except` block,
causing the `run_daily.py` script to crash. This can lead to missed daily cleanup runs
or an unclean container shutdown if the race condition is met during the `on_sigterm`
signal handling.
Also affects:
cron/run_daily.py:36~36
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 3e8ee18. Configure here.
| time.sleep(min(remaining, 60)) | ||
| if current.poll() is None: | ||
| print(f"`{' '.join(command)}` still running at the next scheduled run, stopping it", flush=True) | ||
| stop(current) |
There was a problem hiding this comment.
Past deadlines kill freshly started runs
Low Severity
After a long suspend or clock jump past the computed deadline, run_daily.py still launches sentry cleanup and then immediately treats that run as overdue and stops it. deadline is next_midnight(run_at), so any wake-up more than a day after the missed slot makes seconds_until(deadline) already negative. Catch-up attempts are SIGTERM'd right after start until run_at lands on the current day, so the first successful cleanup can be delayed and a just-started run can be interrupted.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 3e8ee18. Configure here.


Run
sentry-cleanuponsentry-self-hosted-local(the same image and entrypoint asweb) withcron/run_daily.py, which runssentry cleanup --days $SENTRY_EVENT_RETENTION_DAYSevery day at midnight, like the old0 0 * * *crontab. The separate cleanup image, whichapt-get installedcronandgosuand used a bash entrypoint, is gone, and install removes the oldsentry-cleanup-self-hosted-localimage../cronis mounted read-only at/cron, like./healthcheck.Each run gets its own process group. If a run is still going at the next midnight, it is stopped (SIGTERM, then SIGKILL after 60s) before the next one starts.
sentry cleanuphas no lock and can hang, e.g. itsJoinableQueue.join()never returns if a worker is killed mid-task; with cron, a stuck run kept running while the next day's run overlapped it. On container stop, SIGTERM is forwarded to the current run.Cleanup runs as the
sentryuser directly instead of viagosu, and its output still goes to the container logs.Behavior change: users who override the
sentry-cleanupcommand with a crontab line indocker-compose.override.ymlneed to switch to the new command form.Part of making self-hosted run on the distroless sentry image by changing only
SENTRY_IMAGE.