Skip to content

benchmarks: don't crash the run when sending to a closed hub IPC channel - #77

Open
adstep wants to merge 1 commit into
yjs:masterfrom
adstep:adstep-benchmark-ipc-send-crash-fix
Open

adstep wants to merge 1 commit into
yjs:masterfrom
adstep:adstep-benchmark-ipc-send-crash-fix

Conversation

@adstep

@adstep adstep commented Oct 14, 2026 •

Copy link
Copy Markdown

When a benchmark hits its withTimeout limit, the runner moves on, but the benchmark's promise keeps running in the background. If that promise later calls cluster.collect() after its hub processes were stopped or replaced, child.send on the closed IPC channel emits an unhandled 'error' event (ERR_IPC_CHANNEL_CLOSED) on the ChildProcess. That crashes the whole run.

Hit this in a full run. Y2.5 timed out after 45 minutes. About an hour later, Y4.4 restarted the cluster with more server processes, and the stuck Y2.5 promise called collect() on the old, dead children:

Error [ERR_IPC_CHANNEL_CLOSED]: Channel closed
    at target.send ...
    at request (benchmarks/src/cluster.js)
    at Cluster.collect ...
    at ... y2-connections.js

Fix

request in benchmarks/src/cluster.js now passes a callback to child.send. With a callback, Node passes a send failure to it instead of emitting 'error'. The callback removes the listeners and rejects, so the late call fails inside the benchmark that was already abandoned, which is harmless.

Validation

I gave a Cluster a hub child process that had already exited and called collect():

  • Before: the process crashed with an unhandled ERR_IPC_CHANNEL_CLOSED thrown from request.
  • After: collect() rejects with ERR_IPC_CHANNEL_CLOSED and the process keeps running.

npx standard benchmarks/src/ and npx tsc --skipLibCheck also pass. I didn't do a full benchmark run.

A benchmark that hits its timeout keeps running in the background. If it later calls cluster.collect() after its hub processes were stopped or replaced, child.send emitted an unhandled ERR_IPC_CHANNEL_CLOSED 'error' and killed the whole run. Passing a send callback makes Node report the error there, so the late call rejects inside the abandoned benchmark instead.

Copilot-Session: dae4a0ce-dfc4-425b-8f0e-68c3ceda6055
@adstep
adstep marked this pull request as ready for review October 14, 2026 03:13
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.

1 participant