Gate periodic library-mutating tasks behind a scan-leader lease #1
Reference in New Issue
Block a user
Delete Branch "benvin/scan-leader-election"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
In a multi-pod deployment every pod runs the scheduled-task timers, so periodic
library-mutating tasks (library refresh, people and chapter refresh, audio
normalization, media-segment and keyframe extraction, collection and user-data
cleanup, database optimization) fire concurrently against the shared database
and library. That duplicates work and races the pods against each other.
How
IScanLeaderLeaseabstraction that elects a single scan leader througha Redis TTL lease keyed on the pod identity, mirroring the existing transcode
lease machinery.
RedisScanLeaderLeaseacquires or renews the lease with an atomic Lua scriptand fails safe: when Redis is unreachable it treats the pod as leader, so
scans never stall (every pod scanning is preferable to none).
NullScanLeaderLeasepreserves single-instance behavior when election isdisabled or no Redis connection is configured.
ScheduledTaskWorker: when election isenabled and a task key is in the gated set, a non-leader re-arms its trigger
and skips enqueueing. Manual and API-triggered runs bypass this path and still
run on any pod.
TaskManagerinto each worker. The newworker constructor parameters are optional, so behavior is unchanged when
election is off.
Jellyfin:ScanLeaderand reuses the existingJellyfin:TranscodeStore:RedisConnectionString.Covered by unit tests for lease acquire/renew/takeover semantics, the Redis
fail-safe path, and worker gating (a non-leader skips a gated periodic task
while manual execution and non-gated tasks still run).