You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Upgrade Notes
Playlist auto-sync no longer runs by default. If you relied on the background playlist scheduler, it is now off after upgrade and manual/explicit syncs are unaffected. To restore automatic syncing, set PLAYLIST_AUTO_SYNC=1 (accepts 1/true/yes/on); tune the cadence with PLAYLIST_AUTO_SYNC_INTERVAL (default 300 s, minimum 60). No migration or other operator action is required.
Changed
Playlist auto-sync is now opt-in (default OFF).PLAYLIST_AUTO_SYNC defaults to off; set it to 1/true/yes/on to enable the background scheduler. Manual/explicit playlist sync is unchanged. When enabled, the scheduler no longer does a ~30 s first wake (the old min(30, interval)); it honors PLAYLIST_AUTO_SYNC_INTERVAL (default 300, minimum 60) from the first run.
Fixed
Library background disk reconcile now reaches an already-open page, and polling is bounded regardless of library_version churn (follow-up to the fast-tree work below). When a cache is served past its TTL the backend returns it with both reconciled:true and reconciling:true and refreshes it in the background; the Library view derived its "keep polling" state only from reconciled === false, so after the TTL it showed stale disk state and the background refresh never reached the open page until the user re-navigated. It now keeps polling while reconciling === true as well, and picks up the refreshed tree in place. The poll budget is also no longer reset when library_version changes, so a backend that churned the version on every response can no longer poll forever — it terminates at the bounded stall/retry UI.
Cold Library fast tree now shows albums and stops the frontend polling forever (follow-up to the fast-tree work below). The cold-cache fast tree requested the album year field, which is not in the plugin's album field allowlist, so the read returned HTTP 400 and every album was silently dropped (only singletons showed); album year is now derived from the item rows instead. The cold fast response also emitted a fresh library_version on every call (it fell back to time.time() while the cache was cold), which reset the frontend's poll budget every 2 s; it now emits a stable version that only changes once reconciled data is available. The background disk reconcile is now scheduled only after the fast build succeeds, so an offline engine no longer queues a doomed reconcile job behind every failed page load.
Library view paints instantly and fills in disk state in the background. The Library screen now renders from the first (possibly reconciled:false) /api/library response without a blocking spinner, shows a subtle non-blocking "checking disk" indicator while the backend reconciles disk state, and polls /api/library with a bounded backing-off cadence until reconciled becomes true (or the library_version changes) to pick up disk-only and missing-on-disk items. Polling stops once reconciled or after a bounded budget (a stalled check offers a manual retry instead of spinning). The heavy include_tracks=1 pull is still fetched lazily (on track search / album expand), not on first paint.
Library listing no longer blocks on a synchronous NFS disk walk.GET /api/library (without a limit) used to build its artists/albums tree by walking the whole music tree on disk on the request thread whenever the shared cache was cold or stale — and the cache was only kept warm by the opt-in legacy local scan, so on deployments with that scan disabled every page load paid for the full walk (measured ~120s to time out on a 411-album NFS library). The request path now serves the cached disk-reconciled payload when warm, otherwise an engine-only fast tree built with no music-tree/NFS disk walk (it still reads the small local artist-image cache, never the music tree), and runs the disk reconciliation (files missing on disk shown red, plus disk-only/not-imported files) as a deduped background job_engine job that warms the cache for later loads. The disk-missing/disk-only feature is preserved, just moved off the page-load critical path. The response carries a reconciled flag (true once the served payload includes disk state). ?refresh=1 now schedules a background rebuild instead of blocking the request. In-process callers that need the full disk-reconciled tree synchronously (the acquisition-queue build job, which already runs in the background) pass block=True and keep the previous behavior. Cold-cache loads when the engine is offline return the existing ENGINE_OFFLINE 503 instead of a 500.