Skip to content

orly-repl: don't abort in-flight entries on stdin EOF; let exit flush (#542) - #543

Merged
ohohoreilly merged 1 commit into
masterfrom
fix/542-repl-eof-race
Jul 7, 2026
Merged

ohohoreilly merged 1 commit into
masterfrom
fix/542-repl-eof-race

Conversation

@ohohoreilly

Copy link
Copy Markdown
Member

Closes #542. Unblocks #539 (its docker gate is what exposed this).

Bug

printf '40 + 2;\n:quit\n' | orly-repl ... printed the banner and one prompt, then exited 0 with no result and no error. Two defects compounding:

  1. readline's close (stdin EOF) fired while the first entry was still compiling, and the handler quit immediately — closing the WebSocket and deleting the scratch dir under the in-flight entry.
  2. process.exit(0) truncated the aborted entry's pending stderr write, making the failure silent.

Interactive use never hits it (stdin stays open), and the existing smoke held its stdin pipe open until after :quit — which is why CI on #536 was green while #539's printf | docker run -i gate failed.

Fix

  • Stdin EOF chains quit() onto the serialized entry queue: quit happens after pending entries drain. Ctrl-D semantics unchanged.
  • quit() sets process.exitCode instead of calling process.exit; with stdin, readline, and the socket closed, the event loop drains naturally and output always flushes.

Verification

…#542)

With piped stdin (printf ... | orly-repl, the docker repl mode's
shape), readline's close event fires as soon as input is exhausted --
while the first entry is still compiling. quit() ran immediately,
tearing down the WebSocket and scratch dir under the entry, and
process.exit(0) then truncated the pending stderr write, so the
failure was silent: banner, one prompt, exit 0, no output. The
interactive path never hits this because stdin stays open; the smoke
held its pipe open too, which is why CI on #536 was green.

Stdin EOF now chains quit() onto the entry queue (quit after pending
entries drain -- Ctrl-D semantics unchanged), and quit sets
process.exitCode instead of calling process.exit, letting the event
loop drain and output flush once stdin, readline, and the socket are
all closed.

The smoke gains a piped-EOF regression scenario: write an expression,
close stdin immediately, require the result and exit 0. Verified
additionally inside the published docker image against the exact
failing invocation from the docker gate on #539.
@ohohoreilly ohohoreilly self-assigned this Jul 7, 2026
@ohohoreilly
ohohoreilly merged commit 9716c4a into master Jul 7, 2026
9 checks passed
@ohohoreilly
ohohoreilly deleted the fix/542-repl-eof-race branch July 7, 2026 22:05
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.

orly-repl: piped-stdin EOF aborts in-flight entries and process.exit truncates their output

1 participant