Skip to content

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

Description

@vpetersson

Summary

After adding the first asset to a fresh install, the viewer stays on the standby screen indefinitely and logs Playlist is empty, even though the asset is enabled, active, and visible to both the server and viewer via the ORM. More broadly, the viewer's polling-based playlist refresh no longer detects asset edits at all under WAL.

Reproduced on a freshly-flashed x86 (Debian 13) install running master.

Root cause

The viewer detects DB changes by polling the main anthias.db file's mtime:

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

refresh_playlist() only calls update_playlist() when get_db_mtime() > last_update_db_mtime (or on a shuffle reshuffle, or when a deadline passes).

Since #3015 the database 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 anthias.db file's mtime stays frozen until a checkpoint, which during normal operation is infrequent. So get_db_mtime() never advances and the poller never sees the change.

The two fallbacks don't save it:

  • An empty starting playlist yields a None deadline (_compute_deadline returns None when there are no candidates), so the deadline path never fires — this is why the first asset is the most visible failure.
  • For a non-empty playlist the deadline is the soonest end_date, which is typically far in the future, so edits still aren't picked up promptly.

This is a regression introduced by #3015 (WAL) — the viewer's change-detection was not updated to account for WAL's sidecar files.

Reproduction

  1. Fresh install, empty playlist.
  2. POST /api/v2/assets with an enabled, currently-active asset.
  3. Viewer keeps logging Playlist is empty; the asset never appears.
  4. touch ~/.anthias/anthias.db (bump the main file's mtime) → viewer immediately logs Generating asset-list… Showing asset ….

Proposed fix

Make the change-detector WAL-aware: take the newest mtime across anthias.db, anthias.db-wal, and anthias.db-shm. Every commit updates the -wal/-shm mtime, and a checkpoint bumps the main file, so the max advances on every write regardless of journal mode. (Considered PRAGMA data_version as an alternative; the max-mtime approach keeps the existing cheap filesystem-stat design with no per-loop query.)

Related observations (not part of this fix)

  • The v2 create endpoint (AssetListViewV2.post) returns 201 without send_to_viewer('reload'), unlike update/delete — so there's no push-path backstop on create.
  • _handle_reload() reloads settings/rotation/skip-if-inactive only; it does not refresh the playlist (relies on the poller).
  • processing.py celery publishes raw 'reload' without the viewer topic prefix the subscriber splits on — suspected to be dropped; unverified.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions