feat: graceful run termination reports real results on abort (#36) - #41
Merged
Conversation
Aborting a run now sends a Terminate frame (with the run ID) instead of immediately destroying the socket. Rust, parked in its bridge-wait poll loop, consumes it, terminates the run, and returns a real ERR_ABORTED Result carrying durationMs, cpuTimeMs, and the bridge-call records collected so far — so aborted runs (including every durable-isolates suspension) keep their telemetry instead of synthesized zeros. TS waits a short grace period (100ms) for that Result and reuses the now still-healthy connection; if none arrives (sandbox stuck in a tight synchronous loop, so Rust never reads the frame) it falls back to today's socket teardown + synthesized result. Prompt interruption of a busy isolate remains deferred per DESIGN.md §14.7.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #36.
Problem
Aborting a run destroyed the socket; Rust saw EOF and reclaimed the isolate but never sent a Result frame, so the TypeScript side fabricated the aborted
RunResult(durationMs: 0,cpuTimeMs: 0,bridgeCalls: []). Because durable-isolates suspension is implemented as an abort, every suspension lost its timings and per-call bridge records.Approach
Terminateframe (0x07) carrying the run ID instead of tearing the socket down.Terminate,terminate_execution()s, and returns a realERR_ABORTEDResult withdurationMs,cpuTimeMs, and the bridge-call records collected so far.index.tsremaps theERR_ABORTEDResult tostatus: 'aborted'with the abortreason, keeping the telemetry. If no Result arrives (sandbox stuck in a tight synchronous loop, so Rust never reaches the frame read), it falls back to today's socket teardown + synthesized zeros.Prompt interruption of a purely CPU-bound (busy) isolate stays deferred per DESIGN.md §14.7 — the CPU guard remains the backstop; a code comment at the poll-loop site documents this.
Changes
parse_terminate_payload(ipc.rs);RunError::Aborted+ poll-loopTerminatehandling (v8.rs);ERR_ABORTED/AbortErrormapping (wire.rs); session main-loop now ignores a stray Terminate instead of closing (keeps the slot poolable).encodeTerminatePayload(ipc.ts); graceful terminate + grace/fallback indrainUntilResult(client.ts); graceful-abort remap inindex.ts; stale-comment fixes in types.ts.ERR_TERMINATED→ERR_ABORTED), DESIGN.md §5.2/§14.7; changeset (minor).Testing
terminate_frame_aborts_run_with_telemetry,parse_terminate_payload,aborted_maps_to_err_aborted.pnpm fmt:native:check,pnpm lint,pnpm typecheckclean.