[GH-ISSUE #2916] [Bug] Real browser fixture teardown waits on speculative HTTP connections #1027

Closed
opened 2026-10-15 18:30:28 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @N0zoM1z0 on GitHub (Oct 13, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2916

The shared real-browser fixture can wait indefinitely during HTTP-server teardown when a connection opens without sending request headers. The complete browser verifier awaits this cleanup in finally, so any earlier assertion/error remains hidden while cleanup waits.

Confirmed reproduction

Pinned main d4f0c5e664e26fe7ed1566dcc4b85ea9b57d52da, actual Windows x64 Node24.18.0:

  1. Start startBrowserVerifierSite() from scripts/fixtures/browser-verifier-site.mjs.
  2. Control: fetch its HTTP origin and consume the body; site.close() settles within3s.
  3. Start a fresh fixture; connect a retained node:net socket to its origin, without sending HTTP headers.
  4. Call site.close(): it is still pending after3s.
  5. Destroy that same recorded client socket: the pending close settles.

Fresh diagnostic result:

{"ordinary_http_closed":true,"speculative_tcp_closed_before_destroy":false,"closed_after_destroy":true,"root_cause_of_full_browser_run_established":false,"node":"v24.18.0","platform":"win32"}

The diagnostic uses real local sockets and no browser/mocked provider. Its enclosing owned Job settled with zero processes:8.92s elapsed,33.1MiB peak Job commit, two shared logical CPUs and BelowNormal priority.

Producing boundary

The fixture terminates its tracked WebSocket clients and awaits WebSocket-server closure, then awaits server.close() without force-closing its accepted HTTP connections. Other fixture producers already handle this boundary: commit e5bc4e85ec5669399ea506233632b118dead0692 fixed speculative browser connections in the scenario-storage fixture.

Expected: fixture teardown must close the fixture's own accepted connections and listener, independently of whether a client sends headers. Preserve WebSocket teardown and handle ownership; do not increase deadlines or hide earlier verifier failures.

Fresh actual Edge scripts/verify-real-browser.mjs reached this audit's300s enclosing budget; the last marker was closing fixture site, then the outer Job terminated with zero descendants. That composite run used729MiB Job commit; memory did not reach the2GiB bound.

The socket probe proves a fixture cleanup gap, not the root cause of that full Edge timeout. The ten-minute CI composite lane and an earlier functional failure must be assessed separately; source shows a pending finally can mask that earlier error. Add a small real-socket regression and rerun the actual browser workflow with useful phase/error diagnostics.

Local raw diagnostic/source/receipts: /tmp/rea-windows-e2e-20261013/results/browser-close-probe.*. This issue will be handled serially after the preceding Windows audit fixes.

Originally created by @N0zoM1z0 on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2916 The shared real-browser fixture can wait indefinitely during HTTP-server teardown when a connection opens without sending request headers. The complete browser verifier awaits this cleanup in `finally`, so any earlier assertion/error remains hidden while cleanup waits. ## Confirmed reproduction Pinned main `d4f0c5e664e26fe7ed1566dcc4b85ea9b57d52da`, actual Windows x64 Node24.18.0: 1. Start `startBrowserVerifierSite()` from `scripts/fixtures/browser-verifier-site.mjs`. 2. Control: fetch its HTTP origin and consume the body; `site.close()` settles within3s. 3. Start a fresh fixture; connect a retained `node:net` socket to its origin, without sending HTTP headers. 4. Call `site.close()`: it is still pending after3s. 5. Destroy that same recorded client socket: the pending close settles. Fresh diagnostic result: ```json {"ordinary_http_closed":true,"speculative_tcp_closed_before_destroy":false,"closed_after_destroy":true,"root_cause_of_full_browser_run_established":false,"node":"v24.18.0","platform":"win32"} ``` The diagnostic uses real local sockets and no browser/mocked provider. Its enclosing owned Job settled with zero processes:8.92s elapsed,33.1MiB peak Job commit, two shared logical CPUs and BelowNormal priority. ## Producing boundary The fixture terminates its tracked WebSocket clients and awaits WebSocket-server closure, then awaits `server.close()` without force-closing its accepted HTTP connections. Other fixture producers already handle this boundary: commit `e5bc4e85ec5669399ea506233632b118dead0692` fixed speculative browser connections in the scenario-storage fixture. Expected: fixture teardown must close the fixture's own accepted connections and listener, independently of whether a client sends headers. Preserve WebSocket teardown and handle ownership; do not increase deadlines or hide earlier verifier failures. ## Related full-workflow observation and limits Fresh actual Edge `scripts/verify-real-browser.mjs` reached this audit's300s enclosing budget; the last marker was `closing fixture site`, then the outer Job terminated with zero descendants. That composite run used729MiB Job commit; memory did not reach the2GiB bound. The socket probe proves a fixture cleanup gap, **not the root cause of that full Edge timeout**. The ten-minute CI composite lane and an earlier functional failure must be assessed separately; source shows a pending `finally` can mask that earlier error. Add a small real-socket regression and rerun the actual browser workflow with useful phase/error diagnostics. Local raw diagnostic/source/receipts: `/tmp/rea-windows-e2e-20261013/results/browser-close-probe.*`. This issue will be handled serially after the preceding Windows audit fixes.
bsakaguchi 2026-10-15 18:30:28 +00:00
Author
Owner

@morluto commented on GitHub (Oct 14, 2026):

Addressed on main in eca18e08ac80ac838eef78788bf82429bbb30673.

The browser fixture closes speculative idle HTTP connections and tracked WebSockets during teardown; a real idle TCP regression covers this owner.

Validation: Affected suites passed in the merged 65-file run (1169 passed, 2 explicit skips), with full static/architecture checks and documentation checks passing. Final installed-package verification is recorded separately in the audit. Verifier trust-boundary controls cover unavailable lineage, terminal modes, idle TCP teardown, and shared fixture cleanup; no real-provider verifier success is inferred.

Verification scope: Controlled source and production-boundary verification on macOS with pinned Node 24.18.0; real external engines and Windows hosts were not independently rerun. Closure covers the described source defect, not broader provider conformance or performance.

<!-- gh-comment-id:6159224893 --> @morluto commented on GitHub (Oct 14, 2026): Addressed on main in [eca18e08ac80ac838eef78788bf82429bbb30673](https://github.com/morluto/rea/commit/eca18e08ac80ac838eef78788bf82429bbb30673). The browser fixture closes speculative idle HTTP connections and tracked WebSockets during teardown; a real idle TCP regression covers this owner. Validation: Affected suites passed in the merged 65-file run (1169 passed, 2 explicit skips), with full static/architecture checks and documentation checks passing. Final installed-package verification is recorded separately in the audit. Verifier trust-boundary controls cover unavailable lineage, terminal modes, idle TCP teardown, and shared fixture cleanup; no real-provider verifier success is inferred. Verification scope: Controlled source and production-boundary verification on macOS with pinned Node 24.18.0; real external engines and Windows hosts were not independently rerun. Closure covers the described source defect, not broader provider conformance or performance.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1027
No description provided.