WebTransport sendGroup support (and improve sendOrder)#3467
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds WebTransport send group support to the QUIC transport and HTTP/3 layers, implementing the spec requirement that WebTransportSendGroups are treated as bandwidth-equals with per-group sendOrder namespacing. The changes introduce a SendGroupId type, per-group scheduling queues with round-robin fairness at the transport layer, and session-scoped send group registration/validation at the HTTP/3 layer.
Changes:
- New
SendGroupIdandSendGrouptypes inneqo-http3, with a global atomic counter for unique IDs and a sentinel value (0) reserved for ungrouped streams. - Transport-layer scheduling refactored from flat
sendordered/regularqueues to per-groupPerGroupQueueswith round-robin between groups and sendOrder-based priority within each group. - HTTP/3 APIs for creating, registering, and validating send groups on WebTransport sessions, including stream creation with send group assignment.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
neqo-http3/src/features/extended_connect/send_group.rs |
New file: SendGroupId newtype with atomic counter and SendGroup struct |
neqo-http3/src/features/extended_connect/mod.rs |
Adds pub mod send_group |
neqo-http3/src/features/extended_connect/webtransport_session.rs |
Session-level send group registration, validation, and storage |
neqo-http3/src/features/extended_connect/webtransport_streams.rs |
WebTransportSendStream gains send_group field and trait impls |
neqo-http3/src/features/extended_connect/session.rs |
Protocol trait extended with send group methods; forwarding impls |
neqo-http3/src/lib.rs |
Re-exports SendGroupId; adds Stream/SendStream trait methods |
neqo-http3/src/connection.rs |
Http3Connection gains send group set/clear, register/validate, and stream creation with send group |
neqo-http3/src/connection_client.rs |
Public API: webtransport_set_sendgroup, webtransport_register_send_group, webtransport_create_stream_with_send_group |
neqo-transport/src/send_stream.rs |
PerGroupQueues, refactored SendStreams with per_group IndexMap and round-robin scheduling |
neqo-transport/src/streams.rs |
New SendGroupId type alias and set_sendgroup forwarding |
neqo-transport/src/connection/mod.rs |
Public stream_sendgroup API on Connection |
neqo-http3/src/features/extended_connect/tests/webtransport/sessions.rs |
Comprehensive tests for send group creation, validation, cross-session rejection, fair bandwidth allocation, and sendOrder within groups |
c2bb439 to
58be5ff
Compare
|
Given the large merge conflicts, can you do another rebase before review? Can also review now, though I am afraid comments might get lost. |
|
It needs a rebase so CI runs |
c140eef to
723a367
Compare
9c15fa5 to
9a89365
Compare
|
This PR is part of a stack of 16 bookmarks:
Created with jj-stack |
d564de8 to
f5b9bdc
Compare
ad6bc41 to
c62d0f9
Compare
a43f069 to
72179ea
Compare
c62d0f9 to
2a10483
Compare
72179ea to
8988d8f
Compare
2a10483 to
df28806
Compare
larseggert
left a comment
There was a problem hiding this comment.
Lots of new code without test coverage. Tests would benefit from DRY helpers.
bef4997 to
f05bd91
Compare
fc08f9a to
f6a6257
Compare
Merging this PR will not alter performance
Comparing Footnotes
|
f05bd91 to
9430ea7
Compare
f6a6257 to
1d61673
Compare
9430ea7 to
1421dfb
Compare
1d61673 to
d7f1de8
Compare
Failed Interop TestsQUIC Interop Runner, client vs. server, differences relative to
All resultsSucceeded Interop TestsQUIC Interop Runner, client vs. server neqo-pr as client
neqo-pr as server
Unsupported Interop TestsQUIC Interop Runner, client vs. server neqo-pr as client
neqo-pr as server
|
1421dfb to
d33a540
Compare
d7f1de8 to
ca788cc
Compare
Benchmark resultsSignificant performance differences relative to d33a540. streams/walltime/1000-streams/each-1000-bytes: 💔 Performance has regressed by +2.7023%. time: [37.694 ms 37.733 ms 37.773 ms]
change: [+2.5430% +2.7023% +2.8562] (p = 0.00 < 0.05)
Performance has regressed.
Found 6 outliers among 100 measurements (6.00%)
2 (2.00%) low mild
3 (3.00%) high mild
1 (1.00%) high severestreams-flow-controlled/walltime/1-streams/each-4194304-bytes: 💔 Performance has regressed by +2.5199%. time: [33.753 ms 33.801 ms 33.850 ms]
change: [+2.2485% +2.5199% +2.7779] (p = 0.00 < 0.05)
Performance has regressed.streams-flow-controlled/walltime/10-streams/each-1048576-bytes: 💔 Performance has regressed by +2.0618%. time: [90.167 ms 90.467 ms 90.782 ms]
change: [+1.4458% +2.0618% +2.6392] (p = 0.00 < 0.05)
Performance has regressed.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) low severe
1 (1.00%) high severeAll resultstransfer/1-conn/1-100mb-resp (aka. Download): No change in performance detected. time: [166.88 ms 167.41 ms 168.09 ms]
thrpt: [594.92 MiB/s 597.34 MiB/s 599.22 MiB/s]
change:
time: [-0.7993% -0.3761% +0.0771] (p = 0.10 > 0.05)
thrpt: [-0.0770% +0.3775% +0.8058]
No change in performance detected.
Found 4 outliers among 100 measurements (4.00%)
1 (1.00%) low mild
2 (2.00%) high mild
1 (1.00%) high severetransfer/1-conn/10_000-parallel-1b-resp (aka. RPS): Change within noise threshold. time: [268.82 ms 270.99 ms 273.17 ms]
thrpt: [36.607 Kelem/s 36.902 Kelem/s 37.199 Kelem/s]
change:
time: [+0.3758% +1.4640% +2.5179] (p = 0.01 < 0.05)
thrpt: [-2.4560% -1.4429% -0.3744]
Change within noise threshold.
Found 3 outliers among 100 measurements (3.00%)
3 (3.00%) high mildtransfer/1-conn/1-1b-resp (aka. HPS): No change in performance detected. time: [38.471 ms 38.629 ms 38.810 ms]
thrpt: [25.767 B/s 25.887 B/s 25.993 B/s]
change:
time: [-0.2791% +0.2663% +0.8698] (p = 0.36 > 0.05)
thrpt: [-0.8623% -0.2656% +0.2799]
No change in performance detected.
Found 6 outliers among 100 measurements (6.00%)
6 (6.00%) high severetransfer/1-conn/1-100mb-req (aka. Upload): Change within noise threshold. time: [171.14 ms 171.46 ms 171.81 ms]
thrpt: [582.05 MiB/s 583.23 MiB/s 584.31 MiB/s]
change:
time: [+0.5929% +1.0782% +1.4682] (p = 0.00 < 0.05)
thrpt: [-1.4469% -1.0667% -0.5894]
Change within noise threshold.
Found 3 outliers among 100 measurements (3.00%)
2 (2.00%) high mild
1 (1.00%) high severestreams/walltime/1-streams/each-1000-bytes: No change in performance detected. time: [566.32 µs 568.35 µs 570.71 µs]
change: [-0.5849% -0.0562% +0.4861] (p = 0.84 > 0.05)
No change in performance detected.
Found 10 outliers among 100 measurements (10.00%)
2 (2.00%) high mild
8 (8.00%) high severestreams/walltime/1000-streams/each-1-bytes: Change within noise threshold. time: [11.581 ms 11.602 ms 11.625 ms]
change: [-1.0766% -0.5368% -0.1422] (p = 0.01 < 0.05)
Change within noise threshold.
Found 3 outliers among 100 measurements (3.00%)
3 (3.00%) high mildstreams/walltime/1000-streams/each-1000-bytes: 💔 Performance has regressed by +2.7023%. time: [37.694 ms 37.733 ms 37.773 ms]
change: [+2.5430% +2.7023% +2.8562] (p = 0.00 < 0.05)
Performance has regressed.
Found 6 outliers among 100 measurements (6.00%)
2 (2.00%) low mild
3 (3.00%) high mild
1 (1.00%) high severestreams-flow-controlled/walltime/1-streams/each-4194304-bytes: 💔 Performance has regressed by +2.5199%. time: [33.753 ms 33.801 ms 33.850 ms]
change: [+2.2485% +2.5199% +2.7779] (p = 0.00 < 0.05)
Performance has regressed.streams-flow-controlled/walltime/10-streams/each-1048576-bytes: 💔 Performance has regressed by +2.0618%. time: [90.167 ms 90.467 ms 90.782 ms]
change: [+1.4458% +2.0618% +2.6392] (p = 0.00 < 0.05)
Performance has regressed.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) low severe
1 (1.00%) high severetransfer/walltime/pacing-false/varying-seeds: Change within noise threshold. time: [19.028 ms 19.052 ms 19.085 ms]
change: [-1.5707% -1.3738% -1.1746] (p = 0.00 < 0.05)
Change within noise threshold.
Found 5 outliers among 100 measurements (5.00%)
1 (1.00%) low mild
3 (3.00%) high mild
1 (1.00%) high severetransfer/walltime/pacing-true/varying-seeds: Change within noise threshold. time: [19.666 ms 19.682 ms 19.698 ms]
change: [-0.7779% -0.6371% -0.5125] (p = 0.00 < 0.05)
Change within noise threshold.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mildtransfer/walltime/pacing-false/same-seed: Change within noise threshold. time: [19.149 ms 19.164 ms 19.181 ms]
change: [-0.5857% -0.3587% -0.1835] (p = 0.00 < 0.05)
Change within noise threshold.
Found 4 outliers among 100 measurements (4.00%)
2 (2.00%) low mild
1 (1.00%) high mild
1 (1.00%) high severetransfer/walltime/pacing-true/same-seed: Change within noise threshold. time: [19.574 ms 19.596 ms 19.619 ms]
change: [-2.5563% -2.3622% -2.1924] (p = 0.00 < 0.05)
Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severeDownload data for |
I can't find any items needing resolution; will dismiss and request re-review
d33a540 to
31eb305
Compare
ca788cc to
53b10d4
Compare
Fixes existing bug where low priority streams could be starved forever: After the highest-sendOrder stream within a group exhausted its queued data (but remained open), PerGroupQueues::next_stream_id() kept returning it, permanently starving lower-sendOrder streams in the same group.
31eb305 to
28a5ad3
Compare
53b10d4 to
7166b6a
Compare
Client/server transfer resultsPerformance differences relative to 28a5ad3. Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.
Table above only shows statistically significant changes. See all results below. All resultsTransfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.
Download data for |
No description provided.