Commit Graph
3 Commits
Author SHA1 Message Date
ChuckandClaude Opus 5.5 84043468ca feat(vegas): ESPN fetches give way to the render thread too
The hourly sports refresh froze hdpi's Vegas scroll for 1.9s: about twenty
espn-chunk threads fetching and parsing at once, and the render thread
(and the stall watchdog) queued behind all of them for the GIL. The
prefetch gate only covered the prefetch thread.

Vegas now makes its gate the active one (render_gate.set_active), and
render_gate.yielding() gives way through it when there is one and does
nothing otherwise. espn_dates wraps each chunk fetch in it (behind the
same import fallback as json_body, for the copies plugins bundle), and the
background data service wraps each worker. The render thread is never
gated -- the first thread to swap is exempt, and a plugin pushing a live
refresh from its update thread cannot take its place -- and nested blocks
keep the outermost frame as the boundary for the lock checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 16:40:55 -04:00
ChuckandClaude Opus 5.5 1afb2383cd feat(vegas): prefetch_gate on by default, after an A/B/C soak on hdpi
Two runs per arm, about 81,000 frames each, order A B C C B A:

  A  step 1 as is            0.90% late, 20.1 per 10k two+ refreshes late
  B  switch_interval_ms 1    0.78% late, 15.8 per 10k
  C  prefetch_gate           0.60% late,  2.5 per 10k

No freezes in any arm, and the next group was ready at every strip
extension, so parking the prefetch thread (3-6s per 8-minute run) cost
nothing visible. The gate is now on unless vegas_scroll.prefetch_gate is
false; on a stock binding it cannot work and says so at INFO once a run
rather than warning on every install. switch_interval_ms stays off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 16:07:26 -04:00
ChuckandClaude Opus 5.5 4f30bc62ca experiment(vegas): vegas_scroll.prefetch_gate runs the prefetch only while the render thread waits on vsync
The render thread spends most of each refresh in SwapOnVSync with the GIL
released, then needs it back the moment the swap returns. With plugin
rendering on the prefetch thread, it often has to wait for it -- behind
bytecode for up to the switch interval, behind a GIL-holding C call for as
long as that takes -- and hdpi's late frames of 2-5 refreshes went up.

src/common/render_gate.py opens a window around each swap, up to just
before the refresh the swap will return on, and a profile hook on the
prefetch thread parks it outside that window. It is never parked holding a
lock the render thread also takes (the Vegas buffer, cache and state
locks, logging, threading, importlib, the cache), never when no frame has
been swapped for 50ms, and never for more than 50ms at a time.

Off by default and ignored on a binding that keeps the GIL in
SwapOnVSync, where the window would never let the prefetch run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 14:23:09 -04:00