Scheduled tasks missing from GatedTaskKeys run on every replica #14

Closed
opened 2026-09-13 13:33:15 +10:00 by unkin-agent · 0 comments
Member

Context: multi-replica stateless deployment (two 2-replica apps, cheeztv and fafflix, each one PostgreSQL plus valkey, no sticky sessions). Not a 12.0 regression — live in the deployed build. Tracking: #12.

Problem

MediaBrowser.Controller/ScheduledTasks/ScanLeaderOptions.cs:26-36 gates only some timer-driven tasks on the scan leader. Ungated, and therefore running on every replica:

  • DownloadLyrics
  • DownloadSubtitles
  • TmdbRefreshUpcomingEpisodes
  • RefreshTrickplayImages
  • MoveTrickplayImages
  • RefreshInternetChannels
  • RefreshGuide
  • PluginUpdateTask

Consequences: N× duplicate ffmpeg and network work, third-party API quota burned N× over, racing writes to the same rows, and concurrent plugin-assembly writes into the shared /config/plugins.

Scope: this issue is only about the key list. The separate Jellyfin:ScanLeader:Enabled default is handled in PR #11.

Proposal

Add the keys above to GatedTaskKeys.

Add a test pinning every entry of GatedTaskKeys to a task key that actually exists — a key matching nothing silently un-gates its task, so a typo or an upstream rename degrades to the current behaviour with no signal. There is already precedent for this test in the repo.

Acceptance

  • All eight keys present in GatedTaskKeys.
  • A test asserts every entry of GatedTaskKeys resolves to a registered IScheduledTask key, failing on a typo or an upstream rename.
  • A test asserts a non-leader instance does not execute a gated task on its timer trigger.
Context: multi-replica stateless deployment (two 2-replica apps, `cheeztv` and `fafflix`, each one PostgreSQL plus valkey, no sticky sessions). Not a 12.0 regression — live in the deployed build. Tracking: #12. ## Problem `MediaBrowser.Controller/ScheduledTasks/ScanLeaderOptions.cs:26-36` gates only some timer-driven tasks on the scan leader. Ungated, and therefore running on every replica: - `DownloadLyrics` - `DownloadSubtitles` - `TmdbRefreshUpcomingEpisodes` - `RefreshTrickplayImages` - `MoveTrickplayImages` - `RefreshInternetChannels` - `RefreshGuide` - `PluginUpdateTask` Consequences: N× duplicate ffmpeg and network work, third-party API quota burned N× over, racing writes to the same rows, and concurrent plugin-assembly writes into the shared `/config/plugins`. Scope: this issue is only about the key list. The separate `Jellyfin:ScanLeader:Enabled` default is handled in PR #11. ## Proposal Add the keys above to `GatedTaskKeys`. Add a test pinning every entry of `GatedTaskKeys` to a task key that actually exists — a key matching nothing silently un-gates its task, so a typo or an upstream rename degrades to the current behaviour with no signal. There is already precedent for this test in the repo. ## Acceptance - All eight keys present in `GatedTaskKeys`. - A test asserts every entry of `GatedTaskKeys` resolves to a registered `IScheduledTask` key, failing on a typo or an upstream rename. - A test asserts a non-leader instance does not execute a gated task on its timer trigger.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unkin/jellyfin-ha-src#14