fix(ha): gate the remaining timer-driven scheduled tasks #28

Merged
benvin merged 2 commits from benvin/gated-task-keys into main 2026-09-21 07:40:33 +10:00
Member

Seven timer-driven tasks were left out of the scan-leader gate, so every replica ran lyric and subtitle downloads, TMDb upcoming-episode refreshes, trickplay generation, live TV channel and guide refreshes and plugin updates on its own timer: duplicate ffmpeg work, third-party API quota burned N times over, racing row writes and concurrent assembly writes into a shared /config/plugins. MoveTrickplayImages has no default trigger but needs the same gate once an operator schedules it.

  • gate those eight task keys in ScanLeaderOptions.GatedTaskKeys
  • pin the default gated set so dropping a key fails the test
  • scan MediaBrowser.Providers and Jellyfin.LiveTv for task keys, and fail when an assembly declaring scheduled tasks is left out of that scan

Closes #14

Seven timer-driven tasks were left out of the scan-leader gate, so every replica ran lyric and subtitle downloads, TMDb upcoming-episode refreshes, trickplay generation, live TV channel and guide refreshes and plugin updates on its own timer: duplicate ffmpeg work, third-party API quota burned N times over, racing row writes and concurrent assembly writes into a shared /config/plugins. MoveTrickplayImages has no default trigger but needs the same gate once an operator schedules it. - gate those eight task keys in ScanLeaderOptions.GatedTaskKeys - pin the default gated set so dropping a key fails the test - scan MediaBrowser.Providers and Jellyfin.LiveTv for task keys, and fail when an assembly declaring scheduled tasks is left out of that scan Closes #14
unkin-agent added 1 commit 2026-09-20 23:36:43 +10:00
fix(ha): gate the remaining timer-driven scheduled tasks
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
1965c68a76
Add the eight provider, live TV and plugin-update task keys to
ScanLeaderOptions.GatedTaskKeys and widen the test's task-key discovery to
every assembly that declares an IScheduledTask.
Author
Member
  • tests/Jellyfin.Server.Implementations.Tests/ScheduledTasks/ScanLeaderOptionsTests.cs:36-42 — DefaultGatedTaskKeys_Should_MatchRegisteredScheduledTasks only checks GatedTaskKeys.Except(registeredKeys) (gated keys exist as real tasks), never the reverse. Verified by deleting "DownloadLyrics" from ScanLeaderOptions.GatedTaskKeys and rerunning: both tests still pass. This PRs actual fix (the 8 new keys) is not pinned by any test — a future revert of this change would go undetected → assert the gated set against a known/expected list (or assert specific keys are present), not just non-emptiness of the Except.
  • nit: MediaBrowser.Providers/Trickplay/TrickplayMoveImagesTask.cs:58 — GetDefaultTriggers() => []; this task has no periodic trigger, so it does not actually "fire on every replica" as the PR body claims. Gating it is harmless but the stated rationale for including this key is inaccurate.
- tests/Jellyfin.Server.Implementations.Tests/ScheduledTasks/ScanLeaderOptionsTests.cs:36-42 — `DefaultGatedTaskKeys_Should_MatchRegisteredScheduledTasks` only checks `GatedTaskKeys.Except(registeredKeys)` (gated keys exist as real tasks), never the reverse. Verified by deleting `"DownloadLyrics"` from `ScanLeaderOptions.GatedTaskKeys` and rerunning: both tests still pass. This PRs actual fix (the 8 new keys) is not pinned by any test — a future revert of this change would go undetected → assert the gated set against a known/expected list (or assert specific keys are present), not just non-emptiness of the Except. - nit: MediaBrowser.Providers/Trickplay/TrickplayMoveImagesTask.cs:58 — `GetDefaultTriggers() => []`; this task has no periodic trigger, so it does not actually "fire on every replica" as the PR body claims. Gating it is harmless but the stated rationale for including this key is inaccurate.
unkin-agent added 1 commit 2026-09-20 23:55:19 +10:00
test(ha): pin the default gated task key set
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
44b62dcc64
Author
Member

nit: MediaBrowser.Controller/ScheduledTasks/ScanLeaderOptions.cs:54 — gating "PluginUpdates" also silently disables its StartupTrigger (Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs:62): ScheduledTaskWorker.OnTriggerTriggered re-arms a gated-and-skipped trigger with isApplicationStartup: false, and StartupTrigger.Start only fires when that flag is true, so a replica that is not leader at its own boot never gets a startup-triggered plugin-update check again for its process lifetime, silently falling back to the 24h interval trigger → call this out as intended behaviour or add a test for it.

nit: MediaBrowser.Controller/ScheduledTasks/ScanLeaderOptions.cs:54 — gating "PluginUpdates" also silently disables its `StartupTrigger` (Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs:62): `ScheduledTaskWorker.OnTriggerTriggered` re-arms a gated-and-skipped trigger with `isApplicationStartup: false`, and `StartupTrigger.Start` only fires when that flag is true, so a replica that is not leader at its own boot never gets a startup-triggered plugin-update check again for its process lifetime, silently falling back to the 24h interval trigger → call this out as intended behaviour or add a test for it.
benvin merged commit ad50c4e433 into main 2026-09-21 07:40:33 +10:00
Sign in to join this conversation.