You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
lab-ops-hub: Worker-fallback crawler has no fetch timeout — a slow target hangs the crawl indefinitely #500
The Lab Ops Hub Worker-fallback crawler has no fetch timeout, unlike both sibling paths:
Container crawler: pkgs/lab-ops-hub/container/app.py:205 opens with an explicit timeout — _OPENER.open(req, timeout=20).
Container dispatch from the Worker: pkgs/lab-ops-hub/src/index.ts:146 — signal: AbortSignal.timeout(120_000) with a comment explaining it must never hang the request.
No signal, no deadline — neither per hop nor overall.
Why it matters
fetchFollowingValidatedRedirects (src/lib.ts:179) awaits each hop's fetch, and readResponseTextCapped (src/lib.ts:220, #481) then awaits reader.read() until the body ends or the 2 MB cap is reached. The cap bounds bytes, not time: a validated public server that accepts the connection and then responds very slowly — or slow-drips a body at a few bytes per minute — keeps the crawl request (and the Worker invocation) hanging until platform limits kill it, instead of failing fast and returning an error the caller can surface. Every redirect hop multiplies the exposure. This is exactly the hang the container path's 120 s AbortSignal.timeout and the Python crawler's 20 s timeout were written to prevent; the fallback path — the one that runs when the container is already unavailable — was left unprotected.
Evidence
pkgs/lab-ops-hub/src/index.ts:164-166 on main 472726dd: the injected fetcher passes only redirect and headers; no signal.
Dedup: no open or closed issue mentions a crawl/fetch timeout for the Worker fallback (searched crawl timeout, lab-ops-hub).
Suggested fix
Give the fallback fetcher a per-hop timeout mirroring the container crawler, e.g. signal: AbortSignal.timeout(20_000) in the fetch(...) init in crawlFallback (per-hop matches urllib's per-operation timeout semantics; an overall deadline across hops is also acceptable if it is simpler to reason about). A timeout should surface as an ordinary crawl failure (the /api/crawl handler already records containerError/fallback errors), not an unhandled rejection.
Acceptance criteria
A crawl target that accepts the connection but never (or only very slowly) responds fails the fallback crawl within a bounded, documented time instead of hanging.
The timeout applies to every redirect hop, not just the first fetch.
The slow-drip body case is covered: the body read cannot wait indefinitely below the byte cap.
Normal fast crawls and the existing redirect-validation behaviour are unchanged (existing lab-ops-hub test suites still pass).
Activity
Merge pull request #501 from developing-today/creator/500-crawl-fallb…
Merge pull request #525 from developing-today/creator/524-crawl-fetch…