fix(agent): stream videos via ffmpeg-from-URL (no full download) — env-agnostic #181

Merged
bvandeusen merged 1 commits from dev into main 2026-07-01 14:20:54 -04:00
Owner

The failing "poison" jobs were 800 MB+ 4K VR videos: the agent pulled the entire file into memory just to sample a few frames, buffered ~1 GB in RAM, and on a slow/per-connection-limited link got cut off mid-download (ChunkedEncodingError) → failed → re-leased forever.

Environment-agnostic fix (works for any deployment — NFS/CIFS/whatever backs curator — and completes even when slow):

  • media.sample_frames_from_url(): ffmpeg reads curator's /images URL directly, Range-reading only the video index + up to max_frames of content (never the whole file). Reconnect flags resume a dropped transfer; FFMPEG_TIMEOUT (default 1200s, env-tunable) lets a slow link finish. Removed the dead bytes-based sample_frames.
  • worker._download_decode: videos stream (no RAM blowup); stills unchanged. On an ffmpeg miss, client.is_reachable() decides fault (curator up → unprocessable file, stop looping) vs transient (curator down → keep retrying, survives redeploy). Auth header passed so it works whether or not /images is gated.

Follows 2026-07-01.5 (name the real transient reason). Build 2026-07-01.6. CI green (run 1835). Refs #1225.

🤖 Generated with Claude Code

The failing "poison" jobs were 800 MB+ 4K VR videos: the agent pulled the entire file into memory just to sample a few frames, buffered ~1 GB in RAM, and on a slow/per-connection-limited link got cut off mid-download (`ChunkedEncodingError`) → failed → re-leased forever. Environment-agnostic fix (works for any deployment — NFS/CIFS/whatever backs curator — and completes even when slow): - `media.sample_frames_from_url()`: ffmpeg reads curator's `/images` URL directly, Range-reading only the video index + up to `max_frames` of content (never the whole file). Reconnect flags resume a dropped transfer; `FFMPEG_TIMEOUT` (default 1200s, env-tunable) lets a slow link finish. Removed the dead bytes-based `sample_frames`. - `worker._download_decode`: videos stream (no RAM blowup); stills unchanged. On an ffmpeg miss, `client.is_reachable()` decides fault (curator up → unprocessable file, stop looping) vs transient (curator down → keep retrying, survives redeploy). Auth header passed so it works whether or not `/images` is gated. Follows `2026-07-01.5` (name the real transient reason). Build `2026-07-01.6`. CI green (run 1835). Refs #1225. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bvandeusen added 1 commit 2026-07-01 14:20:45 -04:00
fix(agent): stream videos via ffmpeg-from-URL instead of downloading the whole file
CI / lint (push) Successful in 2s
CI / frontend-build (push) Successful in 19s
CI / backend-lint-and-test (push) Successful in 26s
CI / integration (push) Successful in 3m25s
8a0237eeea
The failing "poison" jobs were 800MB+ 4K VR videos: the agent pulled the ENTIRE
file into memory (r.content) just to sample a few frames, which buffered ~1GB in
RAM and — on any slow/contended media store — got cut off mid-download
(ChunkedEncodingError), failed, and re-leased forever. Measured the media read at
~4–6 MB/s (raw off the share, curator out of the path), so no serving-layer tweak
helps; the file simply shouldn't be fully downloaded.

Environment-agnostic fix (works for any deployment, completes even when slow):
- media.sample_frames_from_url(): point ffmpeg straight at curator's /images URL.
  It Range-reads only the video index + up to max_frames of content — never the
  whole file — and reconnect flags resume a dropped transfer instead of failing.
  Generous, env-tunable timeout (FFMPEG_TIMEOUT, default 1200s) = completion over
  speed. Removes the bytes-based sample_frames (dead once videos stream).
- worker._download_decode: videos now stream (no fetch_image, no RAM blowup);
  stills still download+decode. On an ffmpeg miss, probe curator liveness
  (client.is_reachable) → fail the job if curator is up (unprocessable file, stops
  the infinite re-lease) vs release if curator is down (transient, survives a
  redeploy). Auth header passed so it works whether or not /images is gated.

Build marker 2026-07-01.6. Refs issue #1225.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa
bvandeusen merged commit 5ba9871ef0 into main 2026-07-01 14:20:54 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bvandeusen/FabledCurator#181