Skip to content

fix(celery): gate worker startup on applied database migrations - #3016

Merged
vpetersson merged 5 commits into
masterfrom
fix/celery-wait-for-migrations
Jun 7, 2026
Merged

fix(celery): gate worker startup on applied database migrations#3016
vpetersson merged 5 commits into
masterfrom
fix/celery-wait-for-migrations

Conversation

@vpetersson

Copy link
Copy Markdown
Contributor

Issues Fixed

Sentry: ANTHIAS-1 (OperationalError: no such table: assets in normalize_video_asset — 112 events, one burst per device on every upgrade/first boot).

Description

The celery container boots in parallel with anthias-server, whose start script is still running its dbbackupmigrate pass (or the dbrestore fallback, which drops and re-creates every table). A task replayed off the Redis broker in that window dies with no such table: assets, and its on_failure cleanup then fails the same way.

  • Add a worker_init gate that blocks the worker until the unapplied-migration plan is empty (same check as manage.py migrate --check)
  • Probe errors (database locked while the server holds the file, missing django_migrations table on an empty DB) count as not-ready instead of raising
  • Tasks stay queued in the broker while waiting, so nothing is lost — they run as soon as the schema is in place
  • Doing this inside the worker covers every deployment topology (compose, balena, dev, test) without touching the five compose files that each spell out the worker CMD

Checklist

  • I have performed a self-review of my own code.
  • New and existing unit tests pass locally and on CI with my changes.
  • I have done an end-to-end test for Raspberry Pi devices.
  • I have tested my changes for x86 devices.
  • I added a documentation for the changes I have made (when necessary).

🤖 Generated with Claude Code

@vpetersson
vpetersson requested a review from a team as a code owner June 7, 2026 11:09
@vpetersson vpetersson self-assigned this Jun 7, 2026
@vpetersson
vpetersson requested a review from Copilot June 7, 2026 11:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a Celery worker startup gate to prevent the worker from consuming tasks until Django database migrations have been fully applied, addressing a race during upgrades/first boot that caused OperationalError: no such table: assets (Sentry ANTHIAS-1).

Changes:

  • Add a migration-readiness probe (_migrations_ready) that mirrors manage.py migrate --check semantics and treats probe errors as “not ready”.
  • Register a worker_init hook (wait_for_migrations) that blocks worker startup until migrations are ready.
  • Add unit tests covering readiness detection and the blocking/unblocking behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/anthias_server/celery_tasks.py Adds migration readiness polling and a worker_init startup gate to delay worker consumption until the schema is ready.
tests/test_celery_tasks.py Adds tests for migration readiness probing and the worker init waiting loop.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/anthias_server/celery_tasks.py Outdated
Comment thread src/anthias_server/celery_tasks.py

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment thread src/anthias_server/celery_tasks.py
Comment thread src/anthias_server/celery_tasks.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread src/anthias_server/celery_tasks.py

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread src/anthias_server/celery_tasks.py

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

vpetersson and others added 5 commits June 7, 2026 12:40
- The celery container boots in parallel with anthias-server, whose
  start script is still running dbbackup -> migrate (or the dbrestore
  fallback that drops and re-creates every table)
- A task replayed off the Redis broker in that window died with
  OperationalError: no such table: assets — one burst per device on
  every upgrade/first boot (Sentry ANTHIAS-1)
- Block in worker_init until the unapplied-migration plan is empty;
  tasks stay queued in the broker while waiting, so nothing is lost
- Treat probe errors (database locked, missing django_migrations
  table) as not-ready instead of raising
- Works for every deployment topology (compose, balena, dev, test)
  without touching the five compose files that spell the worker CMD

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…ning

- Log the migration-readiness probe's underlying error at DEBUG so a
  persistent non-transient cause is identifiable from device logs
- Repeat the waiting warning every 30s instead of every 5s poll
- Patch time.sleep by dotted path for strict mypy

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- Catch django.db.utils.DatabaseError in the readiness probe; a
  programming bug now fails fast instead of parking the worker in an
  infinite wait
- Reword the docstring to be accurate about DEBUG-level visibility
- Add a fail-fast regression test

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@vpetersson
vpetersson force-pushed the fix/celery-wait-for-migrations branch from 2ff314b to 24042bd Compare June 7, 2026 12:41
@sonarqubecloud

sonarqubecloud Bot commented Jun 7, 2026

Copy link
Copy Markdown

@vpetersson
vpetersson merged commit edcd6f3 into master Jun 7, 2026
9 checks passed
@vpetersson vpetersson mentioned this pull request Jun 9, 2026
5 tasks
vpetersson added a commit that referenced this pull request Jun 9, 2026
- CalVer (YYYY.0M.MICRO); still June 2026, micro 2 -> 3
- Gives Sentry a real release boundary: every build since 2026.6.2
  reported the same base version (only the +git-hash differed), so
  resolved-in-next-release never stuck and fixed issues kept
  reopening on the next event. A version bump lets the deployed
  fixes actually clear from the board.
- Ships the crash/noise fixes merged since 2026.6.2: SQLite WAL +
  busy timeout (#3015), celery migration-gate (#3016) and
  asset-probe soft limits (#3017), transient-redis/CancelledError
  Sentry filtering + redis healthcheck (#3018/#3028), GitHub
  update-check log level (#3019), webview respawn on D-Bus death at
  setup and mid-play (#3020/#3031), resilient static-file scan
  (#3026), Wayland-socket wait (#3030), and Sentry release/board
  triage tags (#3021/#3025)

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
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.

2 participants