Files
redshift ec755bc84c fix(update): bound downloads with a two-tier deadline
`routstrd update` gave the whole release download the same 30 s budget as
the connection: `AbortSignal.timeout(FETCH_TIMEOUT_MS)` was attached to the
fetch, then the 38 MB archive was read with `arrayBuffer()` under that same
signal. Anything slower than ~1.3 MB/s failed with "The operation timed out."
— including the 540 KB/s / 70 s connection this was reproduced on.

Split the deadline in two:

- connect + response headers: 30 s, unchanged. The releases API and
  SHA256SUMS are a few KB, and a hang there is a real failure worth
  surfacing quickly.
- release archive body: 300 s. That is 38 MB / 300 s ≈ 127 KB/s ≈ 1 Mbit/s,
  about 4x headroom over the reproduction, while still bounding the silent
  failure (the command prints no progress) at five minutes.

`fetchOrThrow` now owns an AbortController and reschedules the deadline once
headers arrive, taking a `consume` callback so the body read is covered by
the transfer budget. Aborts report the phase and URL instead of a bare
"The operation timed out."

Also bound `getLatestNpmVersion`, which called `fetch` with no timeout at
all on the same `routstrd update` path; it already returns null on error, so
a stalled registry now degrades to "latest version unknown" instead of
hanging.

Adds regression tests: a body slower than the connect budget must still
install, and a body overrunning the transfer budget must fail with the
phase-aware message.
2026-10-03 11:12:38 +08:00
..