Commit graph

2 commits

Author SHA1 Message Date
Deivid Soto
c82826bf68 fix(trickplay): stop scan-time sprite generation from saturating the host
Some checks failed
CI / Test (push) Failing after 6m21s
CI / Build (push) Successful in 1m34s
CI / Build-1 (push) Successful in 2m0s
CI / Build-2 (push) Successful in 1m33s
CI / Build-3 (push) Successful in 1m38s
CI / Build-4 (push) Successful in 1m35s
CI / Build-5 (push) Successful in 1m38s
CI / Lint (push) Failing after 2m34s
CI / Coverage (push) Failing after 2m44s
CI / Vet (push) Successful in 2m3s
Trickplay sprite generation (one full-decode ffmpeg pass per file) could pin a
machine: multiple agents on the same library decoded the same 4K file at once, no
CPU throttling, and crashed/restarted agents orphaned ffmpeg to init (it ran the
full 45-min decode to completion). Stacked orphans spiked a box to load ~140.

- Single-flight lock: O_CREATE|O_EXCL .lock in the shared sidecar dir so two
  agents watching the same library never decode the same file twice (stale locks
  reclaimed after a TTL). Returns ErrTrickplayInProgress → prewarm skips, not fail.
- Load gate: defer the heavy decode until 1-min load ≤ max(ratio×NumCPU, 1.5),
  capped at 15 min so it throttles without ever becoming a permanent off-switch on
  busy / small hosts. New knob library.prewarm_max_load_ratio (default 0.7).
- Concurrency: trickSem caps trickplay to ONE decode at a time per agent.
- CPU priority: setLowCPUPriority (nice 19) alongside the existing idle ionice.
- No orphans: hardenCmd sets Setpgid + Pdeathsig=SIGKILL, with runtime.LockOSThread
  around the child so the kernel kills ffmpeg exactly when the agent dies (and not
  spuriously — golang/go#27505).

Tests: single-flight/stale-reclaim, load-gate immediate/cancel, and an e2e
Pdeathsig orphan-kill check.
2026-06-04 08:25:00 +02:00
Deivid Soto
1c8cc1c409 perf(stream): run the subtitle/thumbnail prewarm at idle I/O priority
The prewarm's single big read (a ~14 min sequential pass over a 60GB remux to
demux subtitles) shares the same disk/NFS as live streaming. Lower the prewarm
ffmpeg processes to the Linux IDLE I/O class (ioprio_set) so that background
read yields bandwidth to a user who's actually watching — the prewarm slows
down under contention instead of starving playback, and runs full speed when the
disk is idle.

Applied only to the prewarm-only extractors (ExtractSubtitlesVTTMulti,
ExtractThumbnailJPEG) via Start → setIdleIOPriority(pid) → Wait; the on-demand
/sub + /thumbnail handlers keep normal priority (a user is waiting on those).
Linux-only syscall behind a build tag; a no-op stub elsewhere. Best-effort —
errors ignored, never required for correctness.

Verified: the prewarm ffmpeg shows 'idle' under ionice -p; on-demand stays normal.
2026-06-02 11:51:26 +02:00