Skip to content

fix(examples): respect raw streaming proxy backpressure - #2663

Merged
HAYDEN-OAI merged 2 commits into
mainfrom
codex/raw-proxy-backpressure
Sep 7, 2026
Merged

fix(examples): respect raw streaming proxy backpressure#2663
HAYDEN-OAI merged 2 commits into
mainfrom
codex/raw-proxy-backpressure

Conversation

@HAYDEN-OAI

Copy link
Copy Markdown
Contributor

Summary

  • Respect ServerResponse.write(false) in the raw streaming proxy example by waiting for Node's drain event before reading another upstream chunk.
  • Use the existing client-disconnect signal to cancel that wait, and suppress only the matching Node abort rejection. Preserve genuine write, drain, and upstream errors.
  • Extend the existing example regression harness with backpressure, cleanup, same-tick error/disconnect races, and real HTTP transport coverage.

Only the raw example and its handwritten tests change. The Express streaming-helper example, authentication, TLS, origin checks, request handling, SDK runtime, and payload limits are unchanged.

Reproduction

Send a synthetic 16 MiB streamed response through the actual raw-example route and built SDK to a paused local HTTP client. On main, the route consumes all 65 chunks while the client remains paused and queues roughly 14.9 MB in the response.

With this change, the same check pauses upstream consumption, peaks at 262,282 buffered bytes for 256 KiB chunks, and either delivers the complete 16 MiB after the client resumes or cancels the upstream request when the client disconnects. It leaves no drain, close, or error listeners behind. These are observed fixture results, not a new payload cap.

Validation

  • Original focused regressions: 7 failed / 38 passed before the production change.
  • Independent adversarial review caught a genuine response-error/disconnect race in the first candidate. Both added error-first regression cases failed before the correction and pass afterward.
  • Final four-suite example checks: 81 passed on exact Node 22.0.0, Node 24.19.0, and Node 26.2.0.
  • Independent actual-route race/cancellation review: 18 checks passed across Node 22.0.0 and 24.19.0, including unrelated AbortError-shaped errors, synchronous write failures, and listener cleanup.
  • Final actual-source, built-SDK HTTP proof passes on Node 22.0.0, 24.19.0, and 26.7.0: exact 16 MiB resume delivery, disconnect abort, bounded response queue, and cleanup.
  • Full canonical handwritten suite: 7,811 tests passed across 205 files. Canonical formatting/lint, pinned TypeScript checking, CJS/ESM build, and git diff --check pass.

The generated resource suite and remaining platform integrations are left to CI.

@HAYDEN-OAI
HAYDEN-OAI requested a review from a team as a code owner September 6, 2026 23:21
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 6, 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-09-06T23:37:30.530899Z 912c68a New commits
🔒 Security Review Completed 2026-09-06T23:39:08.513683Z 912c68a New commits
ℹ️ 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.

@openai-sdks

openai-sdks Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

OkTest Summary

237/237 SDK tests passed in 10.447s for Node SDK PR #2663.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 147ms
tests/chat-completions-create.test.ts ✅ Passed 236ms
tests/chat-completions-stream.test.ts ✅ Passed 268ms
tests/files-content-binary.test.ts ✅ Passed 200ms
tests/files-create-multipart.test.ts ✅ Passed 143ms
tests/files-list-pagination.test.ts ✅ Passed 151ms
tests/initialize-config.test.ts ✅ Passed 140ms
tests/instance-isolation.test.ts ✅ Passed 99ms
tests/models-list.test.ts ✅ Passed 124ms
tests/responses-background-lifecycle.test.ts ✅ Passed 189ms
tests/responses-body-method-errors.test.ts ✅ Passed 330ms
tests/responses-cancel-timeout.test.ts ✅ Passed 237ms
tests/responses-cancel.test.ts ✅ Passed 198ms
tests/responses-compact-retries.test.ts ✅ Passed 265ms
tests/responses-compact.test.ts ✅ Passed 199ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 129ms
tests/responses-create-advanced.test.ts ✅ Passed 151ms
tests/responses-create-disconnect.test.ts ✅ Passed 1.143s
tests/responses-create-errors.test.ts ✅ Passed 201ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 151ms
tests/responses-create-retries.test.ts ✅ Passed 321ms
tests/responses-create-stream-failures.test.ts ✅ Passed 216ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 2.164s
tests/responses-create-stream-wire.test.ts ✅ Passed 2.548s
tests/responses-create-stream.test.ts ✅ Passed 84ms
tests/responses-create-terminal-states.test.ts ✅ Passed 252ms
tests/responses-create-timeout.test.ts ✅ Passed 219ms
tests/responses-create.test.ts ✅ Passed 178ms
tests/responses-delete.test.ts ✅ Passed 255ms
tests/responses-input-items-errors.test.ts ✅ Passed 246ms
tests/responses-input-items-list.test.ts ✅ Passed 191ms
tests/responses-input-items-options.test.ts ✅ Passed 112ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 243ms
tests/responses-input-tokens-count.test.ts ✅ Passed 268ms
tests/responses-malformed-inputs.test.ts ✅ Passed 2.191s
tests/responses-not-found-errors.test.ts ✅ Passed 279ms
tests/responses-parse.test.ts ✅ Passed 197ms
tests/responses-retrieve-retries.test.ts ✅ Passed 229ms
tests/responses-retrieve.test.ts ✅ Passed 230ms
tests/responses-stored-method-errors.test.ts ✅ Passed 588ms
tests/retry-behavior.test.ts ✅ Passed 2.916s
tests/sdk-error-shape.test.ts ✅ Passed 278ms

View OkTest run #34067322708

SDK merge (290b9b35df88) · head (912c68a18b5a) · base (7b5d1209090f) · OkTest (2b1bdfd25e98)

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Castiron custom code

✅ No new custom-code files detected.

32 mixed files remain; 0 existing customizations changed.

Compared 7b5d1209090f912c68a18b5a. Generated baselines verified.

32 existing customizations unchanged
  • api.md
  • scripts/castiron/README.md
  • scripts/castiron/custom_code_report.py
  • scripts/castiron/test_custom_code_report.py
  • src/client.ts
  • src/resources/audio/transcriptions.ts
  • src/resources/audio/translations.ts
  • src/resources/beta/assistants.ts
  • src/resources/beta/beta.ts
  • src/resources/beta/index.ts
  • src/resources/beta/responses/internal-base.ts
  • src/resources/beta/responses/responses.ts
  • src/resources/beta/threads/index.ts
  • src/resources/beta/threads/runs/index.ts
  • src/resources/beta/threads/runs/runs.ts
  • src/resources/beta/threads/threads.ts
  • src/resources/chat/completions/completions.ts
  • src/resources/chat/completions/index.ts
  • src/resources/conversations/index.ts
  • src/resources/embeddings.ts
  • src/resources/files.ts
  • src/resources/fine-tuning/checkpoints/permissions.ts
  • src/resources/images.ts
  • src/resources/responses/internal-base.ts
  • src/resources/responses/responses.ts
  • src/resources/skills/skills.ts
  • src/resources/skills/versions/versions.ts
  • src/resources/vector-stores/file-batches.ts
  • src/resources/vector-stores/files.ts
  • src/resources/webhooks/index.ts
  • src/resources/webhooks/webhooks.ts
  • tests/lib/data-residency.test.ts

A changed generated baseline means this report cannot reliably identify which handwritten lines changed.

Inspect the custom-code diff

Download the exact patch produced by this run (requires repository access):

gh run download 34067337990 --repo openai/openai-node \
  --name castiron-custom-code-34067337990-1 --dir /tmp/castiron-custom-code-34067337990-1
git apply --stat /tmp/castiron-custom-code-34067337990-1/custom-code.patch
cat /tmp/castiron-custom-code-34067337990-1/custom-code.patch

Or reproduce it from an SDK checkout containing the vendored reporter:

git fetch --no-tags origin 7b5d1209090f82f56b4971976147b5c2a859452e 912c68a18b5a05a33a073f21e9bfe3f00ceb2f82
python3 scripts/castiron/custom_code_report.py report \
  --base 7b5d1209090f82f56b4971976147b5c2a859452e \
  --head 912c68a18b5a05a33a073f21e9bfe3f00ceb2f82 --fetch --require-head-hash --public \
  --out /tmp/castiron-custom-code-912c68a18b5a
cat /tmp/castiron-custom-code-912c68a18b5a/custom-code.patch

This is the current full custom patch for mixed files, not an attribution of only the handwritten lines changed by this PR.

Full report and patch

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed exact head 88c9ff8.\n\nThe raw streaming example now correctly stops pulling upstream chunks after res.write() reports backpressure, resumes on drain, and cancels that wait through the existing client-disconnect signal. The abort filtering is appropriately strict: it suppresses only the exact Node AbortError/ABORT_ERR tied to this disconnect signal and preserves genuine write, drain, and upstream failures, including same-tick error/disconnect races. Listener cleanup remains covered on every tested path.\n\nVerified locally at the exact head:\n- focused disconnect/backpressure/security regression suite: 47/47 passed\n- oxlint passed for both changed files\n- oxfmt check passed\n- git diff --check passed\n\nNo unresolved review threads and no in-scope blocking findings.

@markstuart-oai markstuart-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed exact head 88c9ff8 against freshly fetched main/base 7b5d120. One maintainability issue below should be addressed before approval: the test file grows from 835 to 1,063 lines while duplicating its HTTP lifecycle fixture. The raw example grows from 215 to 242 lines.

The production boundary uses the appropriate Node primitive, events.once. Its narrow abort/cause check preserves error-first failures even when disconnect follows in the same tick; reusing the SDK's broad isAbortError or introducing competing wait promises would weaken this. I found no additional in-scope correctness/security defect. Express behavior, auth/TLS/origin/request handling, SDK runtime and payload limits are unchanged.

Independently executed:

  • Canonical four focused suites: 81/81 on Node 22.23.2 and 24.20.0.
  • Eight actual-route event/write probes plus two built-SDK localhost HTTP probes on each version. Upstream consumption stayed paused at 21 chunks; maximum response queue was 262,310 bytes; resume delivered all 16 MiB; disconnect canceled upstream with listener cleanup. Base failed the same queue assertion at about 11 MB buffered. These are fixture observations, not limits.
  • CJS/ESM build, changed-file pinned lint/format checks, and diff whitespace check passed.

Validation limits: initial localhost checks hit the environment proxy; a process-local localhost exemption fixed them. Type-checking remains blocked by missing example dependencies (express, dotenv, @azure/identity). I did not rerun the author's 7,811-test suite, 18-check harness, exact Node 22.0.0/26 matrix, or platform integrations. The HTTP probes invoke the actual captured route with real ServerResponse and built SDK, not a full Express/TLS deployment.

Comment thread tests/lib/streaming-example-disconnect-security.test.ts Outdated
Move raw backpressure cases into a focused suite and give the example and HTTP harness one owner. Configure upstream content count and terminal event independently while preserving all 47 cases and their assertions.

@markstuart-oai markstuart-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Re-reviewed all four changed files at 912c68a following author response 5127024766 to my review 5126983318.

The P2 is addressed: both HTTP suites now share one setup/teardown owner, and explicit content/count/terminal-event inputs replace the combined fixture modes. The disconnect suite is 434 lines (835 on base; 1,063 in the first candidate), the focused backpressure suite 198, and the shared harness 474. The raw example remains 242 lines. The split preserves the test descriptions and assertion counts while removing duplicated orchestration. No remaining actionable maintainability, correctness, or security findings.

The production drain/cancel boundary is unchanged from the reviewed implementation. Fresh checks confirm backpressure pauses upstream consumption, matching Node aborts are suppressed, genuine write/error-first failures remain visible, and listeners are cleaned up. Express, auth/TLS/origin/request handling, SDK runtime, and payload limits remain unchanged.

Fresh validation: canonical five focused suites passed 81/81 on Node 22.23.2 and 24.20.0; eight independent route/event probes and two real localhost/built-SDK probes passed on each. During the pause, consumption stayed at 21 chunks and the response queue peaked at 262,310 bytes; resume delivered 16 MiB and disconnect canceled upstream. CJS/ESM build, four-file pinned lint/format checks, and diff whitespace check passed.

Limits: tsc remains blocked by missing example dependencies (express, dotenv, @azure/identity). I did not rerun the author's full 7,811-test suite, 18-check harness, exact Node 22.0.0/26 matrix, or platform integrations. The synthetic HTTP probes exercise the actual captured route and built SDK, not a full Express/TLS deployment.

@HAYDEN-OAI
HAYDEN-OAI added this pull request to the merge queue Sep 6, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 6, 2026
@HAYDEN-OAI
HAYDEN-OAI added this pull request to the merge queue Sep 7, 2026
Merged via the queue into main with commit a11bb1b Sep 7, 2026
38 checks passed
@HAYDEN-OAI
HAYDEN-OAI deleted the codex/raw-proxy-backpressure branch September 7, 2026 17:14
@openai-sdks openai-sdks Bot mentioned this pull request Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants