github Screenly/Anthias v2026.10.0
2026.10.0

3 hours ago

Highlights

A stability release. Every change is a fix, most of them driven by what the fleet was actually reporting from the field.

The celery worker stops killing its own pool children. A soft time limit was armed against the job slot rather than the task body, so on a memory-pressured board a late SIGUSR1 would land on a child that had already finished and gone idle — and billiard's handler raised unconditionally, so the child exited 1. That single defect accounted for the largest issue in the project. The guard now honours the signal only while a task body is actually running, only once that body has reached its own limit, and never for a task that was dispatched without a soft limit at all (#3391).

SQLite is no longer corrupted by its own backups. journal_mode=WAL was re-asserted on every connect, which takes an exclusive lock and raises from inside Django's connection setup — leaking the file descriptor each time, and cascading from database is locked to Too many open files to unable to open database file on one device in a single afternoon. Separately, backups were taring the live WAL sidecars, so a restore replayed one database's log into another and produced database disk image is malformed. Backups now ship a real SQLite snapshot, and a restore clears the stale sidecars (#3383).

The viewer waits for the database schema instead of crash-looping. It previously built its scheduler as soon as the server answered, which is not the same thing as the tables existing — on a slow first boot, or after a restore re-created every table underneath it, the viewer queried a schema that wasn't there and the container restarted into the same race (#3384).

Media tasks fail with a reason instead of a SIGKILL. Five tasks carried a hard time limit and no soft one, so an overrun killed the pool child outright, stranding the asset row at "Processing" with nothing to show the operator. All five now get a soft limit with headroom (#3385).

Expected rejections stop being reported as crashes. An over-cap image, a YouTube 403, a source file deleted mid-flight, and a card whose product name isn't valid UTF-8 are all outcomes, not faults. The last of those was taking out a device's storage monitoring entirely (#3382, #3377, #3387).

Playlists drift less. The per-asset wait is now anchored to the start of the tick rather than applied flat after it, so two players on the same playlist no longer separate by seconds over a few hours (#3328).

Known limitation

The 512 MB Pi 3 A+ class of board remains below the floor for this stack. Pre-release burn-in confirmed it cannot sustain a full four-type playlist — it wedges on a webpage or streaming asset and holds only with a single image asset. This is a long-standing memory ceiling on that hardware, not a change introduced here; the board was already running deep in swap at idle on the previous release. All other boards — Pi 2, Pi 3 (64-bit), Pi 4, Pi 5 and x86 — soaked clean.

What's Changed

Other Changes 🔧

  • fix(celery): stop blanket handlers swallowing the soft time limit by @vpetersson-bot in #3352
  • fix(upgrade): stop the viewer and celery before pulling on low-RAM boards by @vpetersson-bot in #3350
  • chore(deps): bump the github-actions group with 7 updates by @dependabot[bot] in #3355
  • fix(viewer): probe cage's Wayland socket by connecting, and drain the webview crash tail by @vpetersson-bot in #3360
  • chore(deps): bump the github-actions group with 4 updates by @dependabot[bot] in #3371
  • chore(deps-dev): bump the python group with 7 updates by @dependabot[bot] in #3370
  • chore(deps): bump the bun group across 1 directory with 4 updates by @dependabot[bot] in #3369
  • fix(viewer): reclaim a stale anthias.viewer owner instead of retrying past it by @vpetersson-bot in #3374
  • fix(viewer): name the exit status when the webview dies before handshake by @vpetersson-bot in #3375
  • fix(webview): exit 1, not SIGSEGV, when D-Bus registration fails by @vpetersson-bot in #3362
  • fix(viewer): wait for the webview to exit during a rotation bounce by @vpetersson-bot in #3376
  • fix(webview): print a fatal-signal backtrace on every board, not just pi3-64 by @vpetersson-bot in #3372
  • chore(deps-dev): bump sass from 1.105.0 to 1.105.1 in the bun group by @dependabot[bot] in #3378
  • chore(deps-dev): bump the python group with 4 updates by @dependabot[bot] in #3379
  • chore(deps): bump the github-actions group with 6 updates by @dependabot[bot] in #3389
  • chore(deps): bump the bun group with 3 updates by @dependabot[bot] in #3388
  • fix(celery): ignore a soft-timeout signal that arrives with no task running by @vpetersson-bot in #3391
  • fix(db): take the WAL switch off the per-connection path, and stop a restore inheriting a stale WAL by @vpetersson-bot in #3383
  • fix(viewer): wait for the database schema before building the scheduler by @vpetersson-bot in #3384
  • fix(celery): soft-limit the five media tasks that only had a hard one by @vpetersson-bot in #3385
  • fix(assets): stop a deleted asset's normalisation task raising on its own file by @vpetersson-bot in #3377
  • fix(celery): a missing normalisation source is an outcome, not a crash by @vpetersson-bot in #3387
  • fix(assets): handle three error-tracker crashes in the asset pipeline by @vpetersson-bot in #3382
  • fix(viewer): anchor the per-asset wait on the tick start, not a flat duration by @DiasonD in #3328
  • chore(release): bump version metadata to 2026.10.0 by @vpetersson-bot in #3373

New Contributors

Full Changelog: v2026.09.0...v2026.10.0

Don't miss a new Anthias release

NewReleases is sending notifications on new releases.