aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_root_availability.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-19 13:24:53 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-19 13:24:53 +0200
commiteca01c7f970d2d3ab2298f934da9776fe01179c6 (patch)
tree4a106ec9fd13bb91eed236c07d821ab50747d5cc /packages/meshbay-node/tests/test_root_availability.py
parent5d5d55b588401cdd304922b58e2af2fb18c63648 (diff)
downloadmeshbay-eca01c7f970d2d3ab2298f934da9776fe01179c6.tar.gz
fix(node): bound what a transcode may produce, and read ffmpeg's output off the loop
Two things about the same three functions, which write to a temp file with ffmpeg and then read it back. **The read was on the event loop.** These files are ffmpeg's own, under `tempfile.mkstemp` on the system disk, so they are not a group root and there is no spun-down platter to serialise against — which is why they go through `asyncio.to_thread` and not `roots.off_disk`. But a whole transcode read inline is still tens of megabytes of blocking read while nothing else in the node is served. The AST guard now covers the module with no exemption at all, and a second check refuses a direct call to the reading helper: passed to `to_thread` it appears in the syntax tree as a name, called inline it appears as a call. **The audio transcode had no size ceiling**, where the subtitle path beside it has had one all along. The bound is the media cache's rather than memory's: `put_thumb` writes one SQLite row, and the store is 512 MB with least-recently-used eviction, sized for thumbnails, posters and short transcodes. At 192 kbit/s a three-hour source is ~260 MB — one row that evicts most of the cache to fit and is evicted again by the next few thumbnails. Not a size this store can hold usefully. 64 MiB, about forty-five minutes: past any track, any single piece, most sets. It takes away nothing that worked. `AUDIO_TRANSCODE_TIMEOUT_SECS` is 120, so a source long enough to reach this was already liable to be killed mid-transcode; what changes is that the refusal now names the limit it met and the size that met it. Serving audio of that length properly means streaming the conversion instead of buffering it, which is a different feature — recorded in §9.8 rather than left as an implied promise. The stat comes before the read, so an oversized result costs a stat rather than the read and the memory behind it. Twelve `test_sticky_header.py[firefox]` setup errors again: Firefox is still open on this machine, and its `[chrome]` half passes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/tests/test_root_availability.py')
0 files changed, 0 insertions, 0 deletions