From 83a2953a1cd9bd263d5741e1d91f3bd8dbc43c30 Mon Sep 17 00:00:00 2001 From: Josue Zamudio Date: Mon, 31 Aug 2026 01:16:38 +0000 Subject: [PATCH] Proxy: log slow segment transfers (TTFB>3s or total>8s) Distinguishes CDN-side stalls (server sees slow TTFB) from client-path stalls (server fast, user still times out) when fragLoadTimeOut recurs. --- server/app.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/server/app.py b/server/app.py index 73c54e6..dec07d2 100644 --- a/server/app.py +++ b/server/app.py @@ -488,9 +488,12 @@ def _cache_put(url, ct, body): def _seg_stream(r, url, ct): """Forward the CDN's bytes as they arrive; keep the LRU warm for completed downloads (a truncated one would poison the cache).""" - buf, complete = [], False + import time + t0, t_first, buf, complete = time.time(), None, [], False try: for c in r.iter_content(chunk_size=256 * 1024): + if t_first is None: + t_first = time.time() buf.append(c) yield c complete = True @@ -498,6 +501,17 @@ def _seg_stream(r, url, ct): r.close() if complete and buf: _cache_put(url, ct, b"".join(buf)) + # observability: a slow segment is the fragLoadTimeOut culprit. Log + # only the slow ones so normal playback stays quiet. TTFB>3s or + # total>8s means the CDN (or our upstream hop) stalled — that's what + # the browser times out on. If these show ~0s but the user still + # fails, the stall is in *their* path (HTTPS proxy / network), not ours. + ttfb = (t_first - t0) if t_first is not None else None + total = time.time() - t0 + if (ttfb is not None and ttfb > 3) or total > 8: + name = url.rsplit("/", 1)[-1][:40] + print(f"[stream-slow] {name} ttfb={ttfb:.1f}s total={total:.1f}s " + f"bytes={sum(len(b) for b in buf)} complete={complete}", flush=True) def _stream_playlist(url):