Skip to content

fix(viewer): detect DB changes under WAL so new assets load - #3062

Merged
vpetersson merged 2 commits into
masterfrom
fix/viewer-wal-mtime-detection
Jun 11, 2026
Merged

fix(viewer): detect DB changes under WAL so new assets load#3062
vpetersson merged 2 commits into
masterfrom
fix/viewer-wal-mtime-detection

Conversation

@vpetersson

Copy link
Copy Markdown
Contributor

Problem

On a freshly-flashed x86 testbed running master, adding the first asset left the viewer stuck on the standby screen, logging Playlist is empty forever — even though the asset was enabled, active, and visible to both the server and the viewer via the ORM. More broadly, the viewer's polling-based playlist refresh stopped detecting asset edits.

Root cause

The viewer decides when to reload its playlist by polling the database file's mtime, stat'ing only the main anthias.db file:

def get_db_mtime(self) -> float:
    try:
        return path.getmtime(settings['database'])
    except (OSError, TypeError):
        return 0

Since #3015 the DB is opened with PRAGMA journal_mode=WAL. Under WAL, commits are written to the anthias.db-wal sidecar (and update anthias.db-shm); the main file's mtime stays frozen until a checkpoint, which during normal operation is infrequent. So get_db_mtime() never advanced and refresh_playlist() never reloaded.

The fallbacks don't save it: an empty starting playlist yields a None deadline (_compute_deadline returns None with no candidates), so the deadline path can't recover the first asset; and for non-empty playlists the deadline is the soonest end_date, typically far in the future.

This is a regression from #3015 — the viewer's change-detection wasn't updated for WAL's sidecar files.

Fix

Make get_db_mtime() WAL-aware: take the newest mtime across anthias.db, anthias.db-wal, and anthias.db-shm. WAL commits move the sidecars and a checkpoint moves the main file, so the value advances on every write regardless of journal mode. This keeps the existing cheap filesystem-stat design (no per-loop DB query); PRAGMA data_version was considered but rejected for that reason.

Testing

  • New regression test test_get_db_mtime_tracks_wal_sidecar: a write touching only the -wal sidecar is now detected.
  • Full non-integration suite green (1087 passed).
  • Verified live on the x86 testbed: before the fix, touch ~/.anthias/anthias.db was required to make the first asset appear; with WAL-aware detection the viewer picks it up on its own.

Fixes #3061

The viewer polls the database's mtime to decide when to reload its
playlist, stat'ing only the main `anthias.db` file. Since #3015 the
DB is opened with `journal_mode=WAL`, where commits land in the
`anthias.db-wal`/`-shm` sidecars and leave the main file's mtime
frozen until a (rare) checkpoint. So `get_db_mtime()` never advanced
and `refresh_playlist()` never reloaded — most visibly, the first
asset on a fresh install never displayed (its empty playlist also has
a `None` deadline, so the deadline fallback can't recover it either).

Take the newest mtime across `anthias.db`, `anthias.db-wal`, and
`anthias.db-shm`: WAL commits move the sidecars and a checkpoint moves
the main file, so the value advances on every write regardless of
journal mode. Add a regression test that a write touching only the
`-wal` sidecar is detected.

Fixes #3061

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@vpetersson
vpetersson requested a review from a team as a code owner June 11, 2026 09:20
@vpetersson
vpetersson requested a review from Copilot June 11, 2026 09:21

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 fixes a regression in the viewer’s playlist refresh logic when SQLite is running with journal_mode=WAL, where database commits update anthias.db-wal/anthias.db-shm without bumping the main anthias.db mtime—causing the viewer to miss asset changes and never reload an initially-empty playlist.

Changes:

  • Update Scheduler.get_db_mtime() to return the newest mtime across anthias.db, anthias.db-wal, and anthias.db-shm.
  • Add a regression test to ensure WAL-sidecar-only writes advance the detected DB mtime.

Reviewed changes

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

File Description
src/anthias_viewer/scheduling.py Make DB change detection WAL-aware by stat’ing db, db-wal, and db-shm and taking the newest mtime.
tests/test_scheduler.py Add a regression test asserting get_db_mtime() tracks -wal updates.

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

Comment thread tests/test_scheduler.py
The new test created /tmp/fakedb-wal in the shared /tmp; with the now
WAL-aware get_db_mtime(), that sidecar could leak into the concurrent
test_check_get_db_mtime (asserting == 0 on /tmp/fakedb) under
`pytest -n auto`. Use a unique tmp_path dir so the sidecar can't escape.

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

Copy link
Copy Markdown

@vpetersson
vpetersson merged commit 8a4db73 into master Jun 11, 2026
9 checks passed
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.

Viewer misses DB changes under SQLite WAL: first asset on a fresh install never displays

2 participants