Repository navigation
Conversation
Collaborator
Author
|
Status: closed. The tests and the two helpers of this PR are one commit of #44337 now, which is one PR on |
robobun
force-pushed
the
robobun/d972025c/http2-slot-pins
branch
from
October 1, 2026 00:59
06a91c9 to
c93464b
Compare
robobun
force-pushed
the
robobun/d972025c/http2-slot-pins
branch
2 times, most recently
from
October 2, 2026 04:20
676ab8a to
39e6256
Compare
robobun
force-pushed
the
robobun/d972025c/http2-slot-pins
branch
from
October 3, 2026 07:36
39e6256 to
0c708b6
Compare
Collaborator
Author
|
Closing: this is folded into #44337. A review asked for one PR on |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
node:http2server counts the open streams of SETTINGS_MAX_CONCURRENT_STREAMS in JS (#peerInitiatedStreams,src/js/node/http2.ts:4044). node:http2: refuse a stream over the advertised limit before it is opened, on maxSessionInvalidFrames #44337 moves that count to native code. No test says when a stream gives its slot back.maxSessionInvalidFrames(2), the two writes of an error exit ofrequest()(6) and the end of the local half of a stream (4), inconnection.rsandh2_frame_parser.rs.Fix
test/js/node/http2/node-http2-max-concurrent-streams.test.tswith 33 tests, written fornode:testso that node runs the same file. Each test pins one order in which a stream takes a slot or gives it back.Connection::count_invalid_frame,H2FrameParser::close_unsentandStream::end_localreplace the copies.node --teston v26.3.0 passes 29 and skips 4 that are Bun only. The debug build of node:http2: refuse a stream over the advertised limit before it is opened, on maxSessionInvalidFrames #44337 has this source and passestest/js/node/http2/.Behaviour change: none
Background
'stream'event.bun:test.Downsides
Notes
What the tests pin. Raw HTTP/2 client, limit 1 unless the test says another value.
sendTrailers(), compatres.end(), one request per round tripstream.close(CANCEL)andstream.close(NO_ERROR)by the serversetImmediaterespond()that fails in Bun (weight, parent, options,maxSendHeaderBlockLength): 4 tests, Bun onlysession.settings()in'session', in a handler (lower and raise), below the open countserver.updateSettings()before the connectionperformServerHandshake()over a DuplexThe node column comes from the same scenarios as plain scripts on node v26.3.0, and from the test file itself on node.
Why the tests are sequential. They run servers in the test process.
describe.concurrentdoes not make them faster, and each test then waits for the others inside its own timeout.Why a new file. The rule from #37588 and #41305 is that a test of
node:http2passes on Bun and on node.node-http2-rejected-streams.test.tsusesbun:test, so node needs a shim to run it. This file usesnode:testandnode:assert, likenode-http2-continuation.test.ts:node --test test/js/node/http2/node-http2-max-concurrent-streams.test.ts. The 4 tests that node skips need arespond()that fails, and the calls that make it fail in Bun do not fail on node.The three helpers.
count_invalid_framehas the body that both call sites had: node'scount++ > max, thenterminated = trueandon_too_many_invalid_frames().close_unsenthas the two writes (state = CLOSED,rst_code) that each of the six exits had.end_localhas the transition that four places had after this side wrote END_STREAM: CLOSED andfree_resourceswhen the peer has ended, HALF_CLOSED_LOCAL when it has not. The dispatches stay where they are.A reset that Bun can write twice.
stream.close(code)schedules an RST_STREAM, and the destroy that follows schedules one more. When a read comes between the two, both go out. CI showed it on Windows 11 aarch64. The test ofclose(CANCEL)counts each reset once. #43539 removes the second reset.Open PRs on the same lines: #40240 rewrites the six
request()exits.