Repository navigation
fix(celery): celery limits and honest failures: time limits, statement timeout, transient fio errors keep retrying, task health sees swallowed failures - #113
Merged
Conversation
…t timeout, transient fio errors keep retrying, task health sees swallowed failures Findings: PERF-06, PERF-09, READ-01, PERF-08, PERF-18, PERF-20 - Every task gets soft 120 s / hard 150 s time limits; admin imports 2 h. The plots import stops at its soft limit. - Postgres statement_timeout by SERVICE_TYPE: web 15 s, worker/beat 120 s, migrations none. - Transient FIO errors (transport, 429, 5xx) no longer count toward MAX_RETRIES and back off 15 min..2 h; 401 still fails. - Task health records a task returning False as a failure; non-failure False returns became True/None. - expires on periodic tasks below their beat interval; full imports bulk_create in batches of 1000. - Email sends retry 3 times with backoff and log once; dead Celery config removed. Spec: specs/2026-11-02-bcr-09-celery-limits.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI points CELERY_RESULT_BACKEND at a dummy URL, and an eager apply() with a retry stores its result there. Test send_with_retry directly with a fake bound task instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 0 |
| Duplication | -2 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
No task had a time limit and Postgres had no
statement_timeout, so one hung task or query could stop the single-concurrency worker (every email, webhook and FIO refresh). FIO outages counted toward the retry cap, so after ~2.5 h of FIO trouble every active user wasfaileduntil an admin reset. Tasks that catch their error and returnFalselooked healthy on the Task health page. This bounds every task and query, lets FIO outages heal on their own, and makes Task health tell the truth.Changes
Findings: PERF-06, PERF-09, READ-01, PERF-08, PERF-18, PERF-20
gamedata_admin_importgets 2 h. The plots import stops at its soft limit instead of counting it as one failed planet.statement_timeoutfromSERVICE_TYPE: web (django) 15 s, worker/beat (celery) 120 s, migrations (manage, set inentrypoint.sh) none. Every service must keepSERVICE_TYPEset (docker-compose does;Procfilenow does for worker/beat).MAX_RETRIES; they back off by the time since the last success, 15 min..2 h. A 401 still fails at once.Falseas a failure (returned False). Tasks whoseFalsewasn't a failure now returnTrue/None(refresh_planet with nothing due, user refresh skips, warm_market_summary); the FIO webhook task returnsFalseafter logging.expireson periodic tasks below their prod beat interval (measured in Axiom); full importsbulk_createin batches of 1000.email_send_failedonce; dead Celery config (CELERY_WORKER_CONCURRENCY,acks_late/typoignore_resultson cxpc) removed.Task names, beat schedules, log events and fields are unchanged; no API, model or migration change.
How it was verified
uv run ruff check,ruff format --check,ty check,pytest(with coverage) all pass, before and after merging currentmain(bcr-07, no conflicts).statement_timeouttests run on Postgres 16 in Docker:SHOW statement_timeoutis15s, a query past the timeout is cancelled.15s, the worker's2min. With FIO blocked,gamedata_refresh_exchangesshows failing on Task health (returned False) and ok again once FIO is reachable; 12 blocked user FIO refreshes leave the rowretryingwith the error count still 0.Deploy
Backend only. Make sure each service in the deployment sets
SERVICE_TYPE(djangofor the web,celeryfor worker and beat); a missing value means the web's 15 s.🤖 Generated with Claude Code