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):