fix(r5): address the /code-review high round — 10 findings

- HLS sweep only deletes directories matching the session-name shape; the root
  is admin-configurable and may be a shared path
- playlist unwrap picks the first entry that actually downloaded, not entries[0]
- concat quoting keeps backslashes literal (ffmpeg treats them so inside '')
- ArrowUp/Down defer while the focused element can still scroll that way
- the staging fallback skips yt-dlp working files (.part-Frag/.ytdl/.temp/.fNNN)
- the boot HLS sweep runs off the event loop
- volume persistence is debounced (was a setItem per wheel notch) and a spin no
  longer loses notches to the iframe's lagging getVolume
- _Breaker.run owns the whole open/call/record protocol; four call sites shrink
- should_prune extracted and unit-tested, plus RSS error-vs-empty tests
- the worker exits non-zero when the schema never lands
This commit is contained in:
2026-07-23 23:25:06 +02:00
parent 5130584d0a
commit 2a7f49c981
9 changed files with 307 additions and 79 deletions
+5 -2
View File
@@ -1,3 +1,4 @@
import asyncio
import logging
import sys
from contextlib import asynccontextmanager
@@ -69,8 +70,10 @@ async def lifespan(app: FastAPI):
url,
)
# No HLS session survives a restart (they live in this process), so anything still on disk is
# a crashed run's segments — sweep them or they accumulate forever.
swept = plex_stream.sweep_orphans()
# a crashed run's segments — sweep them or they accumulate forever. Off the event loop: the
# first sweep after a long uptime can be gigabytes of `.ts` files, and blocking here delays
# serving (a 502 + a failed post-deploy health probe).
swept = await asyncio.to_thread(plex_stream.sweep_orphans)
if swept:
log.info("swept %d orphaned HLS segment directories", swept)
start_scheduler()