Skip to content

Fix early Issues disconnect handling - #135

Merged
mchwang merged 1 commit into
mainfrom
codex/issue-58-disconnect
Oct 6, 2026
Merged

mchwang merged 1 commit into
mainfrom
codex/issue-58-disconnect

Conversation

@mchwang

@mchwang mchwang commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Outcome

A POST to the Issues refresh endpoint now notices when its response closed while the request body was still being read. The departed HTTP request stops waiting without cancelling server-owned issue retrieval for another caller.

Resolves issue 58.

Reproduction and fix

Baseline: 91e49c16c1e7de8a4551b4a39d86e995f3b4d6e4

A deterministic request-lifecycle gate forces the response close event before the endpoint attaches its listener. Before the fix, IssueBoard.refresh received a live signal and the departed waiter remained pending. The endpoint now checks res.closed || res.destroyed immediately after listener registration, closing the lost-event window.

Validation

Validated head: 67d45023b38df18063e5b09a11ea035d403235ea

  • npm test -- --run test/issue-board.test.ts: 10 passed.
  • New regression: passed 10 consecutive runs during independent review.
  • npm run typecheck: passed.
  • git diff --check origin/main...HEAD: passed.
  • CI: both exact-head runs passed, including typecheck, unit, browser, and configured Docker-backed checks.
  • Full local npm test: interrupted after prolonged concurrent Docker-suite contention. It reported one unrelated review-note persistence timeout; the exact test passed alone (1 passed, 17 skipped).

Review rounds

  • Self-review round 1: no findings.
  • Independent high-effort lifecycle review: no findings.
  • Copilot round 1 (67d4502): approval recommended, balanced effort, no findings, no inline threads. Nothing changed or declined.

Review-lesson audit

  • Early response close missed before listener attachment: covered by the existing async lifecycle rule that treats admitted HTTP requests and background jobs as separate state holders, plus the requirement to reproduce summary-only concerns. This is one-off endpoint wiring; no new rule is needed.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The lifecycle race is correctly guarded and covered by a focused regression test.

Review effort: Balanced
Findings: None

What changed in this PR

Fixes a response-close race in the Issues refresh endpoint without cancelling shared retrieval work.

Changes:

  • Detects responses closed before the close listener is attached.
  • Adds deterministic regression coverage for early disconnects and shared refresh ownership.
File Description
web/​server.ts Handles missed response-close events during Issues refresh.
test/​issue-board.test.ts Tests the early-disconnect race and retrieval continuity.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@mchwang
mchwang merged commit a9a1010 into main Oct 6, 2026
3 checks passed
@mchwang
mchwang deleted the codex/issue-58-disconnect branch October 6, 2026 16:19
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.

2 participants