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'sCapabilities.Devicesentry in_nodesis refreshed onceDetectHardwareAccelerationAsyncfinishes 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 theSlotLedger's capacity resolver ever saw — and everyTryReservefor a real device was refused.TranscodingService.DetectHardwareAccelerationAsynccontinuation — invokes the registered_hardwareDetectedCallbackimmediately after_detectedDevicesis populated, in addition to the existingHardwareDetectedSignalR 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 beforeClusterService.StartAsyncruns: if_detectedDevicesis 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 kicksProcessQueueAsyncon a background task after a successful restore. The pre-2.11.1 path only invoked_onWorkItemQueued(set exclusively byClusterServicefor cluster dispatch), so in standalone mode — where_onWorkItemQueuedisnull— restored items sat inPendinguntil 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,ProcessQueueAsynckick at end ofRestoreToQueueAsyncSnacks/Services/ClusterService.cs— registersUpdateLocalSelfNodeas the hardware-detected callback inStartAsync
Version bumps
Snacks/Controllers/HomeController.cs— health endpoint versionSnacks/Services/ClusterDiscoveryService.cs—ClusterVersionprotocol bump to 2.11.1Snacks/Views/Shared/_Layout.cshtml— footer versionREADME.md— version badgebuild-and-export.bat— Docker tag versionelectron-app/package.json/package-lock.json— version
Full documentation: README.md