From 713a11e39418fc3f690201091db195159eecc3ab Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 1 Jul 2026 16:51:26 -0400 Subject: [PATCH] fix(agent): server-side rate metrics + killable-on-stop ffmpeg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two follow-ups from live debugging of "work/min never populates" and "stopped never reached". 1) jobs/min + downloads/min are now computed in the BACKEND on a fixed cadence (_rate_loop, EWMA) and reported ready-to-show. The rates were derived client-side from poll deltas with a dt<30s guard — but a backgrounded/unfocused browser tab throttles its timers to ~1/min, so every delta exceeded 30s and the guard blanked the rates forever. A server-side rate is independent of how often the tab polls. Frontend just displays s.jobs_per_min / s.downloads_per_min. VERSION → .9. 2) ffmpeg video sampling is now killable on Stop. A downloader stuck in a slow/reconnecting decode (observed: 47s, 230s for one video) couldn't see the stop signal until ffmpeg returned, so Stop detached still-running threads and work kept flowing long after — "stopped" that wasn't really stopped. sample_frames_from_url now runs ffmpeg via Popen and polls a `should_stop` callback every 0.5s, terminating (then killing) the process at once on Stop or the per-video timeout. A stop-killed job is handed back (transient), not failed. Co-Authored-By: Claude Opus 4.8 (1M context) --- agent/fc_agent/app.py | 30 ++++++----------------- agent/fc_agent/media.py | 48 +++++++++++++++++++++++++++++------- agent/fc_agent/worker.py | 53 ++++++++++++++++++++++++++++++++++------ 3 files changed, 91 insertions(+), 40 deletions(-) diff --git a/agent/fc_agent/app.py b/agent/fc_agent/app.py index c6cb747..6ae7a1a 100644 --- a/agent/fc_agent/app.py +++ b/agent/fc_agent/app.py @@ -21,7 +21,7 @@ log = logging.getLogger("fc_agent.app") # Bump on every agent change. The page embeds this and /status reports it; the UI # warns to reload when they differ — so a stale browser-cached page can't be # mistaken for "the new image didn't deploy". (Belt-and-braces with no-store.) -VERSION = "2026-07-01.8 · real start/stop state machine (no more stuck 'stopping')" +VERSION = "2026-07-01.9 · server-computed jobs/min + downloads/min (poll-rate independent)" logbuf.install() cfg = Config.from_env() @@ -252,11 +252,6 @@ _PAGE = """