github derekshreds/Snacks v2.11.1
Snacks v2.11.1

5 hours ago

Snacks v2.11.1

Automated Media Library Transcoder

A point release that unblocks standalone-mode encoding on macOS and Windows. After the v2.11.0 pivot to a shared-SlotLedger-based capacity resolver, two startup races that the master-mode heartbeat timer used to paper over became fatal in standalone mode (where no heartbeat exists): the local node's cached Capabilities.Devices snapshot was taken before async hardware detection finished, so every TryReserve for a real GPU/CPU device was rejected; and RestoreToQueueAsync (the path that re-enqueues unfinished items after a restart) only kicked the cluster dispatcher, which doesn't exist in standalone, so restored items sat in Pending forever. Fresh adds from the UI worked because AddFileAsync already woke the local scheduler — restore was the lone path that didn't. Net effect for a standalone user upgrading to 2.11: autoscan would scan, queue, and then silently never start anything.


Standalone-mode autoscan / restore no longer stalls

Hardware-detection snapshot now propagates to the cluster registry in all roles

  • ClusterService.StartAsync — registers a one-shot post-detection callback via _transcodingService.SetHardwareDetectedCallback(UpdateLocalSelfNode) so the local node's Capabilities.Devices entry in _nodes is refreshed once DetectHardwareAccelerationAsync finishes populating _detectedDevices. In master mode the heartbeat timer already re-snapshots the local node every few seconds and hid the race; in standalone there is no heartbeat, so the initial pre-detection snapshot (synthetic "music" device only, no GPU/CPU) was the only one the SlotLedger's capacity resolver ever saw — and every TryReserve for a real device was refused.
  • TranscodingService.DetectHardwareAccelerationAsync continuation — invokes the registered _hardwareDetectedCallback immediately after _detectedDevices is populated, in addition to the existing HardwareDetected SignalR broadcast. Exceptions are caught and logged so a slow / faulty callback never disables the rest of the post-detection path.
  • TranscodingService.SetHardwareDetectedCallback — late-binding handles the fast-machine race where detection completes before ClusterService.StartAsync runs: if _detectedDevices is already non-null at registration time, the callback fires inline so we don't leak the missed-edge.

RestoreToQueueAsync now also wakes the master-local scheduler

  • TranscodingService.RestoreToQueueAsync — additionally kicks ProcessQueueAsync on a background task after a successful restore. The pre-2.11.1 path only invoked _onWorkItemQueued (set exclusively by ClusterService for cluster dispatch), so in standalone mode — where _onWorkItemQueued is null — restored items sat in Pending until the user manually re-saved a setting or toggled something. AddFileAsync (fresh queue from the UI) was already wired this way, which is why fresh adds worked but restart-restored items did not.

Files Changed

Standalone autoscan / restore fix

  • Snacks/Services/TranscodingService.cs_hardwareDetectedCallback, SetHardwareDetectedCallback, callback fire in detection continuation, ProcessQueueAsync kick at end of RestoreToQueueAsync
  • Snacks/Services/ClusterService.cs — registers UpdateLocalSelfNode as the hardware-detected callback in StartAsync

Version bumps

  • Snacks/Controllers/HomeController.cs — health endpoint version
  • Snacks/Services/ClusterDiscoveryService.csClusterVersion protocol bump to 2.11.1
  • Snacks/Views/Shared/_Layout.cshtml — footer version
  • README.md — version badge
  • build-and-export.bat — Docker tag version
  • electron-app/package.json / package-lock.json — version

Full documentation: README.md

Don't miss a new Snacks release

NewReleases is sending notifications on new releases.