Skip to content

Optimize Node HTTP response handling - #6813

Merged
tim-smart merged 1 commit into
mainfrom
agent/codex-engineer/91264af0
Jul 31, 2026
Merged

Optimize Node HTTP response handling#6813
tim-smart merged 1 commit into
mainfrom
agent/codex-engineer/91264af0

Conversation

@tim-smart

Copy link
Copy Markdown
Contributor

Summary

  • coalesce multi-chunk stream pulls into a single Node response write while preserving the allocation-free single-chunk path
  • cache normalized request methods on ServerRequestImpl
  • make HEAD response completion idempotent and correctly await stream drain after backpressure
  • add regression coverage for HEAD close/end ordering, chunk coalescing, and stream backpressure

Root cause and impact

Streaming batches were written one chunk at a time, and the backpressure loop could clear its drain state after a later successful write. HEAD responses also shared a callback between close and end without guarding repeated invocation. The updated response path reduces chunked-transfer/writev overhead and keeps response completion state correct.

Validation

  • nix develop -c pnpm test --run packages/platform-node/test/NodeHttpServer.test.ts packages/platform-node/test/HttpApi.test.ts packages/platform-node/test/HttpStaticServer.test.ts packages/platform-node/test/HttpStaticServerConditional.test.ts (88 tests)
  • nix develop -c pnpm check
  • nix develop -c pnpm lint-fix

Closes EFF-271

@github-project-automation github-project-automation Bot moved this to Discussion Ongoing in PR Backlog Jul 31, 2026
@changeset-bot

changeset-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c091b9b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 30 packages
Name Type
@effect/platform-node Patch
effect Patch
@effect/opentelemetry Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-deno Patch
@effect/platform-node-shared Patch
@effect/vitest Patch
@effect/ai-anthropic Patch
@effect/ai-openai-compat Patch
@effect/ai-openai Patch
@effect/ai-openrouter Patch
@effect/atom-react Patch
@effect/atom-solid Patch
@effect/atom-vue Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-pglite Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-do Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/docgen Patch
@effect/doctest Patch
@effect/openapi-generator Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@effect-slopcop effect-slopcop Bot added 4.0 bug Something isn't working labels Jul 31, 2026

@pullfrog pullfrog Bot 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.

✅ No new issues found.

Reviewed changes

  • HEAD response idempotency — adds a completed guard in the HEAD path to prevent double resume when the close event fires before the .end() callback returns.
  • Stream chunk coalescing — replaces per-chunk iteration with a single Buffer.concat + nodeResponse.write call, eliminating the needDrain state machine and its correctness bug (a later successful write in the same batch could clear needDrain after drainLatch was already closed).
  • Method caching — caches toUpperCase() on ServerRequestImpl.method via ??=.
  • Tests — three well-scoped regression tests covering HEAD completion ordering, chunk coalescing, and backpressure/drain behavior.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

@github-actions

Copy link
Copy Markdown
Contributor

Bundle Size Analysis

Generated from PR build output; treat the content below as untrusted.

File Name Current Size Previous Size Difference
basic.ts 6.63 KB 6.63 KB 0.00 KB (0.00%)
batching.ts 9.42 KB 9.42 KB 0.00 KB (0.00%)
brand.ts 6.31 KB 6.31 KB 0.00 KB (0.00%)
cache.ts 10.18 KB 10.18 KB 0.00 KB (0.00%)
config.ts 20.04 KB 20.04 KB 0.00 KB (0.00%)
differ.ts 19.93 KB 19.93 KB 0.00 KB (0.00%)
http-client.ts 21.03 KB 21.03 KB 0.00 KB (0.00%)
logger.ts 10.34 KB 10.34 KB 0.00 KB (0.00%)
metric.ts 8.55 KB 8.55 KB 0.00 KB (0.00%)
optic.ts 7.33 KB 7.33 KB 0.00 KB (0.00%)
pubsub.ts 14.47 KB 14.47 KB 0.00 KB (0.00%)
queue.ts 11.15 KB 11.15 KB 0.00 KB (0.00%)
schedule.ts 10.33 KB 10.33 KB 0.00 KB (0.00%)
schema-class.ts 18.86 KB 18.86 KB 0.00 KB (0.00%)
schema-fromJsonSchemaDocument.ts 28.67 KB 28.67 KB 0.00 KB (0.00%)
schema-representation-roundtrip.ts 24.99 KB 24.99 KB 0.00 KB (0.00%)
schema-string-transformation.ts 13.00 KB 13.00 KB 0.00 KB (0.00%)
schema-string.ts 10.65 KB 10.65 KB 0.00 KB (0.00%)
schema-template-literal.ts 14.85 KB 14.85 KB 0.00 KB (0.00%)
schema-toArbitraryLazy.ts 21.66 KB 21.66 KB 0.00 KB (0.00%)
schema-toCodeDocument.ts 24.08 KB 24.08 KB 0.00 KB (0.00%)
schema-toCodecJson.ts 18.91 KB 18.91 KB 0.00 KB (0.00%)
schema-toEquivalence.ts 18.73 KB 18.73 KB 0.00 KB (0.00%)
schema-toFormatter.ts 18.59 KB 18.59 KB 0.00 KB (0.00%)
schema-toJsonSchemaDocument.ts 22.33 KB 22.33 KB 0.00 KB (0.00%)
schema-toRepresentation.ts 19.25 KB 19.25 KB 0.00 KB (0.00%)
schema.ts 18.12 KB 18.12 KB 0.00 KB (0.00%)
stm.ts 12.12 KB 12.12 KB 0.00 KB (0.00%)
stream.ts 9.37 KB 9.37 KB 0.00 KB (0.00%)

@tim-smart
tim-smart merged commit 705d1f1 into main Jul 31, 2026
19 checks passed
@tim-smart
tim-smart deleted the agent/codex-engineer/91264af0 branch July 31, 2026 19:47
@github-project-automation github-project-automation Bot moved this from Discussion Ongoing to Done in PR Backlog Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

4.0 bug Something isn't working

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant