connect is abortable (A24): a guest-discarded dial reclaims its socket - #63
Merged
Conversation
A guest that cancels an in-flight connect — polymorph-iroh's relay dial deadline (its #93/#95) drops the losing future at 10s — previously left the platform WebSocket connecting until this module's own 30s bound fired: polyengine's A23 discard is delivery-only. With the A24 `abortable()` mark, every call receives an AbortSignal the runtime aborts exactly when a guest cancellation discards the call: - mid-handshake, the abort settles the dial connect-failed through the same settle discipline as the connect timer, and closes the socket; - pre-aborted, the dial is refused before a socket exists; - after the handshake, an abort means the resource can never reach the caller, so the connection is closed as undeliverable. Direct callers omit the signal; arity is stable under the mark. Floors move with the import: @polyengine/protocol ^0.2.3 (the mark's first release) in the published module, and the conformance driver's exact pins to the 0.5.1 runtime family + protocol 0.2.3 (the runtime that delivers A23/A24). The A22 pin gate passes on one resolved version per line. Falsified: with the handshake abort listener disabled, the mid-handshake test falls through to the 30s connect bound and fails. Gates: just polyengine-module-check (17/17), just exam-polyengine, just validate-wit. (just check-js fails identically on unmodified main: node --check on js/componentize/websocket.js, pre-existing.)
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.
A guest that cancels an in-flight
connectpreviously left the platform WebSocket connecting until this module's own 30s connect bound fired: polyengine A23's discard is delivery-only ("the host operation itself is not interrupted"). The motivating consumer is polymorph-iroh's new relay dial deadline (polymorph-iroh#93 / polymorph-iroh#95): its guest drops the losing connect future at 10s, and polyengine A24 (polyengine#243) addedabortable()for exactly this — naming this dial as the case to fix.The change
Websocket.connectcarries the A24 mark (stage-3 decorator spelling on the existing static): every call receives anAbortSignalappended after the WIT-declared parameters, aborted by the runtime when — and only when — a guest cancellation discards the call. Three windows:connect-failedbefore a platform socket exists.connect-failed, closes the socket.signal.abortedpre-check covers the sliver between the handshake settle and this registration.Direct callers omit the signal; arity under the mark is stable (A24). The module still couples only to
@polyengine/protocol(A22).Floors
@polymorph/websocket:@polyengine/protocol@^0.2.3— the module now imports the mark, so 0.2.3 is a floor, not a refresh.conformance/driver-ct/polyengine: exact pins move to the 0.5.1 runtime family + protocol 0.2.3 (the runtime that actually delivers A23/A24). The A22 pin gate passes: one resolved runtime-family version, one resolved protocol version across both locks.Consumers pick this up through their normal
@polymorph/websocketrelease/lock refresh; no surface change (the WIT contract is untouched — the signal is embedder-side vocabulary).Tests
isAbortable(Websocket.connect).Deno.listenso the test observes accept and socket teardown): rejectsconnect-failedwell under the 30s bound, and the stub sees the socket reclaimed.Falsified: with the handshake abort listener disabled, the mid-handshake test falls through to the 30s connect bound and fails (
0 passed | 1 failed (30s)).Gates
just polyengine-module-check: pass (17/17)just exam-polyengine: pass (runtime-family pin: 0.5.1,protocol pin: 0.2.3, no@polyengine/runtimespecifier)just validate-wit: passjust check-js: fails identically on unmodifiedmain(node --check js/componentize/websocket.js: ESM-vs-CJSSyntaxErrorunder node 24) — pre-existing, untouched by this PR.