Skip to content

testing: real-socket scope-close TCP teardown test (comms-4lz5) - #15

Merged
GraemeF merged 1 commit into
mainfrom
comms-4lz5
Jun 13, 2026
Merged

GraemeF merged 1 commit into
mainfrom
comms-4lz5

Conversation

@GraemeF

@GraemeF GraemeF commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

The Tier-3 residue of the hexagonal test-architecture epic (comms-e5vm): the one assertion in the suite that genuinely cannot leave the socket — that interrupting an in-flight `FetchHttpClient` long-poll on scope close actually tears down the underlying TCP connection (`AbortSignal → fetch → socket`).

Why this is the only surviving socket test

comms-e5vm.2 (#12) moved every event-pump LOGIC test — gap-replay, 429 retry, BAD_EVENT_QUEUE_ID reconnect, and the Effect fiber-interrupt path of scope close — onto the owned-fake stub HttpClient + TestClock: deterministic, no socket. The stub proves the fiber unwinds. It cannot prove the socket unwinds, because there is no socket. This test closes exactly that gap and is the only surviving `Bun.serve` long-poll in the suite.

The assertion is server-side

A real `Bun.serve` whose long-poll handler parks forever but listens on the request's `req.signal`. When the client tears the connection down, Bun fires that abort — observing it is proof the teardown reached the peer, not merely that our Effect fiber unwound (which the stub already covers). The Effect platform client wires this end to end: `httpClient.make` aborts the request's `AbortController` `onInterrupt`, and `FetchHttpClient` passes that `signal` into `fetch`.

Lifecycle is `Effect.acquireRelease`/`Scope` throughout: the server's release is `server.stop(true)`, and the long-poll is forked into an inner `Effect.scoped` whose close is the interruption under test — so release is guaranteed even on the interruption path. The proof is timeout-guarded, so a non-teardown fails loud (verified by a mutation: detaching the fiber from the scope makes the test time out).

Broader-rework question (comms-4lz5's original scope): recommend leave-as-is

The bead also asked whether to migrate the ~170 `realm.`/`fixture.` hook call sites to a per-test `Effect.scoped` wrapper. That rework was motivated by a contention-driven teardown-starvation flake in the infinite-long-poll tests — which .2 dissolved structurally by moving that logic off the socket. Every fixture still wired through `registerRealmHooks` is now a plain request/response realm that starts and stops in a few ms; there is no teardown-starvation mode left to fix, and the `acquireRelease`/`Scope` shape now lives exactly where it is load-bearing (this one socket test). The migration would be churn across ~170 sites for no behavioural payoff — YAGNI. This PR also refreshes the now-stale `realm-hooks.ts` doc comment that still described the dissolved failure mode.

Closes comms-4lz5.

The Tier-3 residue of the hexagonal test-architecture epic: the one
assertion that genuinely cannot leave the socket — interrupting an
in-flight FetchHttpClient long-poll on scope close actually tears down
the underlying TCP connection (AbortSignal -> fetch -> socket).

comms-e5vm.2 moved every event-pump LOGIC test (gap-replay, 429 retry,
BAD_EVENT_QUEUE_ID reconnect, the Effect fiber-interrupt path of scope
close) onto the stub HttpClient + TestClock — deterministic, no socket.
The stub proves the fiber unwinds; it cannot prove the socket unwinds.
This test closes that gap and is the only surviving Bun.serve long-poll.

The assertion is server-side: a real Bun.serve whose long-poll handler
parks forever but listens on req.signal, so observing the abort proves
the teardown reached the peer rather than just unwinding our fiber.
Lifecycle is Effect.acquireRelease/Scope throughout.

Also refreshes the realm-hooks doc comment, whose forward-reference to
this bead described a teardown-starvation mode that .2 dissolved.
@GraemeF
GraemeF merged commit eb58377 into main Jun 13, 2026
2 checks passed
@GraemeF
GraemeF deleted the comms-4lz5 branch June 13, 2026 10:38
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