Skip to content

test(combos): await the fallback lease release on both passthrough relays - #7360

Merged
lidge-jun merged 1 commit into
devfrom
fix/combo-fallback-cancel-lease
Oct 19, 2026
Merged

lidge-jun merged 1 commit into
devfrom
fix/combo-fallback-cancel-lease

Conversation

@lidge-jun

Copy link
Copy Markdown
Owner

Summary

Fixes the Windows dev CI failure in run 39212576911 (Windows shard 9/9, job 117929528851). tests/server/server-combo-zero-output-failover.test.ts › "accepted fallback keeps its turn lease until stream cancel" expected getActiveTurnCount() to be 0 right after await response.body.cancel(), but got 1.

Diagnosis: the test asserted too early. This is not a lease leak and not a regression from #7354 or #7355. Passthrough SSE uses two relays. Linux and macOS (streamMode: auto) use the tee relay, which unregisters the turn as soon as the client cancels. Windows uses the eager bounded relay (src/server/relay-eager.ts) for no-rewrite traffic on a fixed runtime. By its documented #44 cancel semantics, that relay keeps reading upstream in a bounded discard drain after a client cancel, so a terminal that really arrives is still recorded. It calls onDone (turn unregister, lease release) only when it sees a terminal or the drain window (15 s) expires. The fallback upstream in this test never sends a terminal, so on Windows the turn stays admitted after cancel() by design. The release still happens exactly once, when the drain ends.

Two scenarios do release immediately on every relay: a real client disconnect, because it aborts the request signal that the admission lease watches, and the abort case.

Change (test only): these cases now run on both relay shapes on every OS, using the existing setRelayPlatformForTests seam: linux selects tee, and win32 with streamMode: "eager-relay" selects eager. Linux shards therefore cover the path that only Windows exercised before. The test now:

  • awaits the lease's real release callback instead of asserting synchronously or sleeping;
  • asserts that the eager relay still holds the turn after a body cancel (pins the Request logs can miss successful ChatGPT native passthrough turns #44 behavior);
  • ends that drain with an upstream terminal;
  • still asserts exactly one release and no release miss.

No product code changes.

Verification

  • Reproduced on macOS with Bun 1.4.3 by forcing the eager relay (setRelayPlatformForTests("win32")), using an in-process stress loop under 8 CPU-burner processes:
    • Before (old immediate assertion): cancel failed 150/150 iterations, with a count of 1 and no release yet, exactly the CI symptom. Abort passed 150/150.
    • After (await the release signal): eager cancel and abort 0/150 failures; tee cancel and abort 0/150 failures.
  • The committed file run 40 times through scripts/test.ts under the same load: 40/40 runs green, 16 pass / 0 fail each.
  • bun run typecheck: pass.
  • Full suite and Windows CI not run locally; the Windows shard is left to CI.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed. (None: test-only.)
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults. (No runtime change.)

@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner October 19, 2026 07:31
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-19T07:36:16.885103Z 4af460b PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: c4da4c0f-12ea-404f-b9a9-40fc27b9a268
📥 Commits

Reviewing files that changed from the base of the PR and between ee3ad33 and 4af460b.

📒 Files selected for processing: 1
  • tests/server/server-combo-zero-output-failover.test.ts
+-----------------------------+
| ░R░e░v░i░e░w░ ░i░n░ ░b░i░o░ |
+-----------------------------+
  \
   \     /)/)
        ( '')
        /  |
      o(___)
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lidge-jun
lidge-jun merged commit 955d8c2 into dev Oct 19, 2026
6 of 7 checks passed
@lidge-jun
lidge-jun deleted the fix/combo-fallback-cancel-lease branch October 19, 2026 07:32
@github-actions github-actions Bot added the chore Maintenance, CI, tests, refactors, or build changes (not a user-facing bug or feature). label Oct 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4af460b64f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

expect(getActiveTurnCount()).toBe(1);
expect(releases).toBe(0);
}
try { finish(); } catch { /* the tee relay already cancelled the upstream body */ }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Verify tee cancellation before completing upstream

In the tee/cancel row, calling finish() before checking the release lets the test pass even if cancelling the response no longer releases the lease: the injected terminal will independently finish inspection and unregister the turn. Only the eager row is supposed to need that terminal, so the tee row should assert the release after response.body.cancel() without completing upstream.

Useful? React with 👍 / 👎.

finish();
expect(await response.text()).toContain("held fallback");
}
await releasedSignal;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reset the relay override from afterEach

When a relay regression prevents the release callback, this promise remains pending until Bun times out the test; Bun then runs afterEach without resuming this async function, so the lexical finally never clears setRelayPlatformForTests. Because the existing afterEach does not reset that module-global override, all subsequent passthrough tests in the worker can run under the forced platform and produce cascading or misleading failures. Clear the override in afterEach as well.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Maintenance, CI, tests, refactors, or build changes (not a user-facing bug or feature).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant