Skip to content

fix(streaming): interrupt blocked synchronous SSE reads - #37

Merged
moonyue-w merged 1 commit into
mainfrom
codex/sync-sse-cancellation
Oct 29, 2026
Merged

moonyue-w merged 1 commit into
mainfrom
codex/sync-sse-cancellation

Conversation

@moonyue-w

Copy link
Copy Markdown
Collaborator

Summary

Closing a synchronous Session or Thread SSE subscription from another thread could leave the reader blocked until the server sent more data or the read timeout expired. Interrupt an active HTTP/1.x socket read before releasing its response to the pool so close() promptly ends the subscription without reconnecting.

Why

Installed-package Thread SSE acceptance reproduced this on the real HTTPX transport in both Forward and Managed. Existing mock streams woke readers in their own close() implementation and did not expose the issue. The fix is shared by Session and Thread streams and preserves keep-alive reuse after a fully consumed response.

Verification

  • uv run make lint
  • uv run make typecheck
  • uv run make test: 4,319 passed; 73 account-backed integration cases deselected
  • uv run make docs-check: generated documentation and 34 README snippets passed
  • Example --help smoke checks: 26 passed
  • Account-backed integration tests: a locally built, installed wheel passed 24 targeted CN/Global Forward/Managed synchronous/asynchronous Thread stream checks; all temporary-resource cleanup operations passed

Commands and results:

Before the fix: 4 real HTTP blocked-read cancellation regressions failed.
After the fix: all 10 new regression cases passed in the full test suite.
Installed wheel: 68 synchronous/asynchronous Thread consumer checks passed.
Installed wheel: HTTPS cancellation, keep-alive reuse, and transport guards passed (10 cases).
Python 3.10 + minimum supported HTTPX 0.27.0: HTTP and HTTPS regressions passed (20 cases).
uv run make build: wheel and sdist built.
uv run python .github/scripts/release_notes.py check: passed.
uv run python -m unittest discover -s .github/scripts -p 'test_*.py': 25 passed.

The installed wheel is a local candidate, not a replacement internal QA artifact. After merge, rerun the internal validation pipeline and accept its new package before preparing version PRs. Python 3.13 and Linux are left to the existing GitHub CI matrix.

Impact

  • Public behavior changed; public method signatures are unchanged.
  • User-facing changes added to CHANGELOG.md under Unreleased.
  • Synchronous and asynchronous clients remain aligned; async behavior is unchanged and rechecked.
  • Generated API documentation updated.
  • Contract fixture changes not applicable: no HTTP API contract changed.
  • Go and TypeScript parity considered: their existing candidate packages passed the same cancellation acceptance.
  • Migration notes not required: no breaking API change.
  • No credentials, .env.live, logs, certificates, or generated test output committed.

HTTP/2 sockets can be shared across requests and are never interrupted. HTTP/2 and custom transports without an exposed native socket retain their transport's close behavior; the README documents this boundary.

@moonyue-w
moonyue-w merged commit f0c6939 into main Oct 29, 2026
5 checks passed
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