Skip to content

fix(runtime): stop WASM pipe reads from stalling for maxBlockingReadMs (#1959) - #1965

Merged
abcxff merged 1 commit into
mainfrom
stack/fix-runtime-stop-wasm-pipe-reads-from-stalling-for-maxblockingreadms-1959-knuwtupr
Sep 9, 2026
Merged

abcxff merged 1 commit into
mainfrom
stack/fix-runtime-stop-wasm-pipe-reads-from-stalling-for-maxblockingreadms-1959-knuwtupr

Conversation

@abcxff

@abcxff abcxff commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

A WASM pipeline stage read from a pipe via a synchronous, blocking process.fd_read on the sidecar reactor thread. While parked in that kernel read, the reactor could not run the upstream stage to completion, so the writer never closed its pipe end; the reader only unblocked when the maxBlockingReadMs watchdog fired — once per stage. A low cap turned that into a guest-visible Would block/EAGAIN with a nonzero exit; a high cap into a multi-second-per-stage stall (e.g. env | sort | sed ~20-30s).

Make WASM process.fd_read non-blocking (Some(Duration::ZERO)), mirroring the sibling process.fd_write path: the runner poll+retries a logically-blocking fd on EAGAIN, the reactor stays free to run the writer, and the reader observes EOF promptly. Pipeline latency no longer depends on maxBlockingReadMs.

Add a regression test asserting a low-cap pipeline succeeds without watchdog EAGAIN (with exact-output checks) and that three-stage pipeline latency is independent of the cap.

@abcxff

abcxff commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Stack for rivet-dev/agentos

Get stack: forklift get 1965
Push local edits: forklift submit
Merge when ready: forklift merge 1965

change knuwtupr

@railway-app

railway-app Bot commented Sep 9, 2026

Copy link
Copy Markdown

🚅 Environment agentos-pr-1965 in rivet-frontend has no services deployed.

#1959)

A WASM pipeline stage read from a pipe via a synchronous, blocking process.fd_read on the sidecar reactor thread. While parked in that kernel read, the reactor could not run the upstream stage to completion, so the writer never closed its pipe end; the reader only unblocked when the maxBlockingReadMs watchdog fired — once per stage. A low cap turned that into a guest-visible `Would block`/EAGAIN with a nonzero exit; a high cap into a multi-second-per-stage stall (e.g. `env | sort | sed` ~20-30s).

Make WASM process.fd_read non-blocking (Some(Duration::ZERO)), mirroring the sibling process.fd_write path: the runner poll+retries a logically-blocking fd on EAGAIN, the reactor stays free to run the writer, and the reader observes EOF promptly. Pipeline latency no longer depends on maxBlockingReadMs.

Add a regression test asserting a low-cap pipeline succeeds without watchdog EAGAIN (with exact-output checks) and that three-stage pipeline latency is independent of the cap.
@abcxff
abcxff force-pushed the stack/fix-runtime-stop-wasm-pipe-reads-from-stalling-for-maxblockingreadms-1959-knuwtupr branch from 8b66d9d to 67d2fb7 Compare September 9, 2026 16:41
@abcxff

abcxff commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Fixes #1959

@abcxff
abcxff merged commit 67d2fb7 into main Sep 9, 2026
16 of 19 checks passed
@abcxff
abcxff deleted the stack/fix-runtime-stop-wasm-pipe-reads-from-stalling-for-maxblockingreadms-1959-knuwtupr branch September 9, 2026 17:39
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.

Pipe reader is not woken on writer close: every | stage stalls for maxBlockingReadMs at EOF, then fails with EAGAIN

1 participant