Skip to content

test(node:http): shrink pinned-write payload to 8MB and run concurrently - #36376

Open
robobun wants to merge 1 commit into
mainfrom
farm/da52c690/speedup-node-http-pinned-write
Open

robobun wants to merge 1 commit into
mainfrom
farm/da52c690/speedup-node-http-pinned-write

Conversation

@robobun

@robobun robobun commented Jul 29, 2026 •

Copy link
Copy Markdown
Collaborator

The node:http large Buffer writes are sent zero-copy tests in test/js/node/http/node-http-pinned-write.test.ts timed out in the --parallel CI batch:

test/js/node/http/node-http-pinned-write.test.ts - 5 failing in the parallel batch (450.13s)
✗ Content-Length (non-chunked) path delivers the exact bytes - test timed out
✗ a second write before drain is ordered after the pending tail - test timed out
✗ large string writes (latin1 ascii, utf8 encoding) are held by reference - test timed out
✗ large string writes with latin1 encoding deliver the exact bytes - test timed out
✗ a second write before drain releases the pin on the first buffer - test timed out

Cause

CHUNK_SIZE was 64MB (128MB for the double-write tests). In the parallel batch that much loopback traffic and Buffer.alloc/sha1 work, under ASAN and alongside many other files, pushed each test past the timeout.

Change

  • CHUNK_SIZE 64MB → 8MB. res.write() is synchronous, so the client cannot drain before it returns; the backpressure threshold is the server's kernel send buffer. 8MB overflows the Linux/macOS loopback send buffer (measured pin threshold ~4MB here; the existing RESIZABLE_CHUNK_SIZE tests already used 8MB for the same reason).
  • describe → describe.concurrent so the subprocess tests overlap with the in-process ones.

The node:http server socket's fd is not reachable from JS (res.socket._handle is null; the native us_socket_t* is behind a private Symbol(handle) on JSNodeHTTPServerSocket with no fd getter), and setting the client's SO_RCVBUF via setSocketOptions does not lower the threshold for the first write since the server's send buffer is what fills first. So the payload size, not a socket option, is the lever here.

The pin assertion (detachedWhilePending === false) was already skipIf(isWindows); the other tests assert byte-delivery correctness and pass whether or not the pin engages.

Verification

  • debug+ASAN: 9 pass, wall time 15.6s → 7.7s; the five failing tests drop from 350-670ms to 120-200ms each in isolation
  • 15/15 iterations under debug+ASAN, 0 failures
  • Windows x64 (system bun): 6 pass, 3 skip, 0 fail, 263ms

no test proof · iteration 0 · Platform-specific test-only change; deferring to CI.

64MB per test (up to 128MB for the double-write cases) saturated the
loopback and timed out in the --parallel CI batch. 8MB is enough to
overflow the Linux/macOS kernel send buffer and engage the zero-copy
pin; write() is synchronous so the client cannot drain before it
returns. The pin assertions are already skipIf(isWindows); the
remaining tests check byte-delivery correctness and pass regardless
of whether the pin engages.

Also switch to describe.concurrent so the subprocess tests overlap.

debug+ASAN wall time 15.6s -> 7.7s; the five tests that timed out in
CI drop from 350-670ms to 120-200ms each in isolation.
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@robobun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 9 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 37f24d0b-6b2f-4ae5-af6e-4c496c336cad

📥 Commits

Reviewing files that changed from the base of the PR and between 0c88489 and 9c75eed.

📒 Files selected for processing (1)
  • test/js/node/http/node-http-pinned-write.test.ts

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

@claude claude 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.

LGTM — test-only de-flake that shrinks the workload without weakening what's asserted.

What was reviewed:

  • 8MB still overflows the Linux/macOS loopback send buffer with a paused client, so the pin assertion (detachedWhilePending === false) remains load-bearing; the resizable tests already relied on 8MB for this and RESIZABLE_CHUNK_SIZE is unchanged in value.
  • describe.concurrent: each test binds port: 0, allocates its own payload, and captures results in local closures — no shared state between tests.
  • The five tests that were timing out assert byte-delivery only and pass whether or not backpressure engages, so shrinking the payload doesn't hollow them out.
Extended reasoning...

Overview

Test-only change to test/js/node/http/node-http-pinned-write.test.ts: CHUNK_SIZE 64MB → 8MB, describe → describe.concurrent, and RESIZABLE_CHUNK_SIZE rewritten as CHUNK_SIZE (same value, 8MB). No runtime code touched.

Security risks

None. Test file only; no auth, crypto, or untrusted-input handling changed.

Level of scrutiny

Low-to-moderate. The main risk with a de-flake like this is silently weakening the property the test protects (REVIEW.md: "When de-flaking, keep asserting the property the original assertion protected"). I checked each assertion:

  • The one test that asserts the pin actually engages (detachedWhilePending === false) uses a paused net.Socket client, so the server's kernel send buffer must fill before the client reads anything. 8MB exceeds the Linux/macOS loopback send buffer (the PR measured the threshold at ~4MB, and the pre-existing RESIZABLE_CHUNK_SIZE tests already used 8MB for exactly this reason). Windows was already skipIf'd for this test before the change; the updated comment just documents that.
  • The five tests that were timing out in CI assert byte-for-byte delivery (sha1 match, ordering) and don't depend on backpressure engaging — shrinking the payload doesn't change what they prove.
  • RESIZABLE_CHUNK_SIZE = CHUNK_SIZE is a no-op in value.

For describe.concurrent: every test creates its own server on port: 0, its own payload buffers, and captures results in per-test locals (detachedWhilePending, detachedAfterSecondWrite, etc.). The subprocess tests are fully isolated. No shared mutable state, so concurrent execution is safe. This matches the repo guidance to use test.concurrent for independent subprocess-spawning suites.

Other factors

The PR description reports 15/15 passes under debug+ASAN and a wall-time drop from 15.6s → 7.7s. The change follows the "shrink the workload, don't raise the timeout" rule from REVIEW.md. No prior reviewer comments to address.

@robobun

robobun commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator Author

CI on build #85310: node-http-pinned-write.test.ts passed on every lane (no longer in the parallel-batch timeout list). The 14 failing files are all tagged flaky and none touch this diff.

This branch has not been deployed

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants