Skip to content

Bound the updater's network legs with deadlines - #263

Merged
turinglambdaai merged 2 commits into
mainfrom
fix/distribution-network-deadlines
Oct 16, 2026
Merged

turinglambdaai merged 2 commits into
mainfrom
fix/distribution-network-deadlines

Conversation

@turinglambdaai

Copy link
Copy Markdown
Owner

Closes #249 and #253.

fetch-update-manifest / download-update waited on the network indefinitely, and update checks run on the backend serve thread family-wide, so a black-holed peer parked the update surface forever — the root cause behind every product's private watchdog.

  • copy-limited! waits for byte availability through a peek-bytes-avail!-evt under a stall deadline (default 60 s) with an optional total cap; a stalled peer raises a retryable error.
  • fetch-update-manifest runs its blocking connect inside a custodian-owned worker that a connect+idle deadline (defaults 30+60 s) shuts down; products override via keyword arguments.
  • Deterministic tests: a held-open pipe, a byte-dripping peer that defeats the stall bound, and a never-evt deadline wrapper.

The remaining issues in this cluster (#243/#244/#248/#250/#251/#240 and the DX set) build on these deadlines and follow in separate slices.

fetch-update-manifest and download-update waited on the network
indefinitely, and since update checks run on the backend serve thread
family-wide, one black-holed peer took the update surface down with it —
which is why several products grew private watchdogs around rivet's own
copy loop. The copy loop now waits for byte availability through
peek-bytes-avail!-evt under a stall deadline with an optional total cap,
and the manifest fetch runs its blocking connect inside a
custodian-owned worker that a connect+idle deadline shuts down. Defaults
are 60 seconds idle/stall and 30+60 connect+idle; products override them
per call. Deterministic tests hold a pipe open, drip bytes past the
stall bound, and park the deadline wrapper on never-evt.
fetch-update-manifest and download-update waited on the network
indefinitely, and since update checks run on the backend serve thread
family-wide, one black-holed peer took the update surface down with it —
which is why several products grew private watchdogs around rivet's own
copy loop. The copy loop now waits for byte availability through a
peek-bytes-avail!-evt under a stall deadline with an optional total cap
(handle-evt normalizes the completion to one value), and the manifest
fetch runs its blocking connect inside a custodian-owned worker that a
connect+idle deadline shuts down. Defaults are 60 seconds idle/stall and
30+60 connect+idle; products override them per call. Deterministic tests
hold a pipe open, drip bytes past the stall bound, and park the deadline
wrapper on never-evt.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

distribution: fetch/download have no network timeout — a black-holed peer stalls the backend serve thread

1 participant