feat(background_tasks): worker status admin page - #99
Merged
Conversation
Adds a read-only /background-tasks/workers sub-page that surfaces Celery worker presence (hostname, queues, active count, pool, processed) via celery.control.inspect(). Manual refresh button, no auto-poll, reuses background_tasks.view permission, no sidebar entry.
…and formatTs - Move _stub_celery autouse fixture to a module-scoped opt-in via pytestmark.usefixtures, dedupe across test_admin_api.py and the new test_workers_endpoints.py. - Hoist WorkerInfo/WorkerSnapshot interfaces and formatTs into pages/constants.ts so Detail.tsx and Workers.tsx share them. - Hoist `from background_tasks import worker_inspector as wi` to module scope in test_workers_endpoints.py.
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.
Summary
Adds a read-only
/admin/background-tasks/workerssub-page so operators can see whether a Celery worker is connected to the broker and what each worker is doing — closes the visibility gap where "tasks stuck in pending" was indistinguishable from "no tasks enqueued yet."WorkerInspectorwrapscelery.control.inspect()with a probe-then-inspect flow that disambiguates broker-down from broker-up-with-no-workers. CatchesOperationalError,RedisError,ConnectionError,OSErrorand surfaces them asWorkerSnapshot(broker_reachable=False, error=...)instead of 5xx-ing the page./admin/background-tasks/workers(initial render) and JSON at/api/background_tasks/admin/workers(Refresh button uses plainfetch). Both run the inspector viaasyncio.to_threadso the broker round-trip never blocks the event loop.Workers.tsxpage with three states — broker unreachable, no workers connected, list of worker cards (hostname, online dot, queue badges, active/pool/processed counts, software). Refresh button shows a sonner toast on failure, mirroring the existing retry pattern.Design choices worth flagging
inspect.ping()is a broadcast over the broker; polling every few seconds adds steady chatter for a page operators only glance at. One-click verify is intentional.inspect.*()returnsNonefor both "broker down" and "no workers replied" — operators couldn't tell which.redis.RedisErroris caught explicitly:redis.exceptions.TimeoutError/ConnectionErrordon't inherit from built-inOSErrororConnectionError, so they'd otherwise escape and become 500s. Verified by an authentication-error test case.Test plan
make test— 1054 Python + 8 JS tests pass (33 inmodules/background_tasks/tests/including 4 new inspector unit tests + 4 new endpoint tests covering auth, snapshot payload, broker-unreachable response, and Inertia render).make lint— ruff format/check, ty, biome, tsc, 300-line cap, doctor checks (SM003/SM004/SM018/SM019), metadata, READMEs all clean.make doctor— no new warnings.make devrunning, exercise the three UI states by stopping the broker / starting it without workers / startinguv run python scripts/run_worker.py. Confirm the Index toolbar "Workers" link round-trips.Notes for the reviewer
docs/superpowers/{specs,plans}/2026-05-01-background-tasks-worker-status-page-*.mdfor context._stub_celerytest fixture into a module conftest (opt-in viapytestmark.usefixturesso signal tests still get an unstarted app), and liftsWorkerInfo/WorkerSnapshot/formatTsintopages/constants.tssoDetail.tsxandWorkers.tsxshare them.