Skip to content

Process a connection whose only pending work is an expired datagram - #3988

Closed
jesup wants to merge 7 commits into
users/jesup/expire_datagramsfrom
users/jesup/process_when_only_a_datagram
Closed

jesup wants to merge 7 commits into
users/jesup/expire_datagramsfrom
users/jesup/process_when_only_a_datagram

Conversation

@jesup

@jesup jesup commented Sep 14, 2026

Copy link
Copy Markdown
Member

No description provided.

@jesup

jesup commented Sep 14, 2026 •

Copy link
Copy Markdown
Member Author

Copilot AI 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.

🟡 Changes recommended

The deadline comparison does not match the queue’s strict expiry predicate.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Ensures expired WebTransport datagrams trigger HTTP/3 server connection processing and outcome accounting.

Changes:

  • Detects due datagram expiry during server processing.
  • Adds a test-only enqueue path and regression test.
File summaries
File Description
neqo-http3/src/connection_server.rs Adds expired-datagram processing detection.
neqo-http3/src/server.rs Supplies connection and time context.
neqo-http3/src/webtransport.rs Adds a test-only datagram helper.
neqo-http3/src/features/extended_connect/tests/webtransport/datagrams.rs Tests expiry as the sole pending work.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 1
  • Review effort level: Balanced (auto)

Note

Copilot is running an experiment and ran this review at Balanced.


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread neqo-http3/src/connection_server.rs Outdated
@codecov

codecov Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.89%. Comparing base (bab27a4) to head (07ad55d).

Additional details and impacted files
@@                             Coverage Diff                             @@
##           users/jesup/watermark_priority_eviction    #3988      +/-   ##
===========================================================================
- Coverage                                    96.89%   96.89%   -0.01%     
===========================================================================
  Files                                          119      119              
  Lines                                        41385    41411      +26     
  Branches                                     41385    41411      +26     
===========================================================================
+ Hits                                         40099    40124      +25     
- Misses                                        1260     1263       +3     
+ Partials                                        26       24       -2     
Flag Coverage Δ
freebsd 94.39% <100.00%> (-0.01%) ⬇️
linux 97.10% <100.00%> (+0.01%) ⬆️
macos 95.23% <100.00%> (+0.01%) ⬆️
windows 95.32% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
neqo-common 99.26% <ø> (ø)
neqo-http3 95.35% <100.00%> (+0.01%) ⬆️
neqo-qpack 96.91% <ø> (ø)
neqo-transport 97.86% <ø> (-0.01%) ⬇️
neqo-udp 95.37% <ø> (ø)
mtu 89.13% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed

codspeed Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 81 untouched benchmarks


Comparing users/jesup/process_when_only_a_datagram (07ad55d) with users/jesup/watermark_priority_eviction (bab27a4)

Open in CodSpeed

@jesup
jesup force-pushed the users/jesup/watermark_priority_eviction branch from af88cc2 to 288713f Compare September 14, 2026 05:31
@jesup
jesup requested a review from omansfeld as a code owner September 14, 2026 05:31
@jesup
jesup force-pushed the users/jesup/process_when_only_a_datagram branch from f4bbb65 to d2a658d Compare September 14, 2026 05:31
@jesup
jesup force-pushed the users/jesup/watermark_priority_eviction branch from 288713f to 2053125 Compare September 14, 2026 17:56
@jesup
jesup force-pushed the users/jesup/process_when_only_a_datagram branch from d2a658d to 7057d30 Compare September 14, 2026 17:56
@jesup
jesup force-pushed the users/jesup/watermark_priority_eviction branch from 2053125 to 3c0dfc6 Compare September 16, 2026 03:45
@jesup
jesup force-pushed the users/jesup/process_when_only_a_datagram branch from 7057d30 to e16793a Compare September 16, 2026 03:45
@jesup
jesup force-pushed the users/jesup/watermark_priority_eviction branch from 3c0dfc6 to 5c377c8 Compare September 16, 2026 17:19
@jesup
jesup force-pushed the users/jesup/process_when_only_a_datagram branch from e16793a to 29d2f7b Compare September 16, 2026 17:19
Comment thread neqo-http3/src/features/extended_connect/tests/webtransport/datagrams.rs Outdated
Comment thread neqo-http3/src/connection_server.rs

@mxinden mxinden left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't understand the need for this patch. Can you not react on OutgoingDatagramOutcome from neqo-transport?

@github-actions

Copy link
Copy Markdown
Contributor

Performance profiles for profiler.firefox.com

Benchmarks (14)
  • neqo-bin-main: pr · base
  • neqo-common-decoder: pr · base
  • neqo-http3-streams_simulated: pr · base
  • neqo-http3-streams_walltime: pr · base
  • neqo-transport-frame_decode: pr · base
  • neqo-transport-min_bandwidth: pr · base
  • neqo-transport-pacer: pr · base
  • neqo-transport-packet_codec: pr · base
  • neqo-transport-range_tracker: pr · base
  • neqo-transport-rx_stream_orderer: pr · base
  • neqo-transport-send_streams: pr · base
  • neqo-transport-sent_packets: pr · base
  • neqo-transport-transfer_simulated: pr · base
  • neqo-transport-transfer_walltime: pr · base
Comparisons (5)

@github-actions

Copy link
Copy Markdown
Contributor

Failed Interop Tests

QUIC Interop Runner, client vs. server, differences relative to users/jesup/watermark_priority_eviction at bab27a4.

neqo-pr as clientneqo-pr as server
neqo-pr vs. aioquic: ⚠️C1
neqo-pr vs. go-x-net: BP BA
neqo-pr vs. haproxy: BP BA
neqo-pr vs. lsquic: L1 C1
neqo-pr vs. msquic: Z A L1 C1
neqo-pr vs. mvfst: A
neqo-pr vs. neqo: Z A
neqo-pr vs. nginx: BP BA
neqo-pr vs. ngtcp2: Z L1 ⚠️C1 CM
neqo-pr vs. picoquic: Z A
neqo-pr vs. quic-go: A
neqo-pr vs. quiche: BP BA
neqo-pr vs. s2n-quic: CM
neqo-pr vs. tquic: S BP BA
neqo-pr vs. xquic: S R Z A L1 C1
aioquic vs. neqo-pr: ⚠️C1 CM
go-x-net vs. neqo-pr: CM
kwik vs. neqo-pr: BP BA CM
msquic vs. neqo-pr: 🚀C1 CM
mvfst vs. neqo-pr: Z L1 C1 CM
neqo vs. neqo-pr: Z A
openssl vs. neqo-pr: LR M A CM
quic-go vs. neqo-pr: CM
quiche vs. neqo-pr: CM
quinn vs. neqo-pr: V2 CM
s2n-quic vs. neqo-pr: ⚠️B CM
tquic vs. neqo-pr: 🚀C1 CM
xquic vs. neqo-pr: M CM
All results

Succeeded Interop Tests

QUIC Interop Runner, client vs. server

neqo-pr as client

neqo-pr as server

Unsupported Interop Tests

QUIC Interop Runner, client vs. server

neqo-pr as client

neqo-pr as server

@github-actions

Copy link
Copy Markdown
Contributor

Benchmark results

No significant performance differences relative to bab27a4.

All results
transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1504: Change within noise threshold.
       time:   [131.64 ms 131.82 ms 132.02 ms]
       thrpt:  [757.48 MiB/s 758.60 MiB/s 759.63 MiB/s]
change:
       time:   [-0.9855% -0.7719% -0.5486%] (p = 0.00 < 0.05)
       thrpt:  [+0.5516% +0.7779% +0.9953%]
       Change within noise threshold.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high severe
transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1504: Change within noise threshold.
       time:   [213.97 ms 214.26 ms 214.55 ms]
       thrpt:  [46.610 Kelem/s 46.672 Kelem/s 46.735 Kelem/s]
change:
       time:   [+0.2214% +0.4363% +0.6554%] (p = 0.00 < 0.05)
       thrpt:  [-0.6511% -0.4344% -0.2209%]
       Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) low mild
1 (1.00%) high mild
transfer/1-conn/1-1b-resp (aka. HPS)/mtu-1504: Change within noise threshold.
       time:   [7.4007 ms 7.4048 ms 7.4090 ms]
       thrpt:  [134.97   B/s 135.05   B/s 135.12   B/s]
change:
       time:   [+0.0675% +0.1459% +0.2231%] (p = 0.00 < 0.05)
       thrpt:  [-0.2226% -0.1457% -0.0675%]
       Change within noise threshold.
Found 3 outliers among 100 measurements (3.00%)
1 (1.00%) low mild
2 (2.00%) high mild
transfer/1-conn/1-100mb-req (aka. Upload)/mtu-1504: No change in performance detected.
       time:   [136.58 ms 136.76 ms 136.98 ms]
       thrpt:  [730.02 MiB/s 731.23 MiB/s 732.18 MiB/s]
change:
       time:   [-0.3331% -0.1481% +0.0550%] (p = 0.15 > 0.05)
       thrpt:  [-0.0550% +0.1483% +0.3342%]
       No change in performance detected.
Found 3 outliers among 100 measurements (3.00%)
1 (1.00%) high mild
2 (2.00%) high severe
streams/walltime/1-streams/each-1000-bytes: No change in performance detected.
       time:   [544.70 µs 546.63 µs 548.84 µs]
       thrpt:  [1.7376 MiB/s 1.7446 MiB/s 1.7508 MiB/s]
change:
       time:   [-0.4915% +0.0313% +0.5706%] (p = 0.90 > 0.05)
       thrpt:  [-0.5674% -0.0313% +0.4939%]
       No change in performance detected.
Found 12 outliers among 100 measurements (12.00%)
1 (1.00%) high mild
11 (11.00%) high severe
streams/walltime/1000-streams/each-1-bytes: No change in performance detected.
       time:   [10.480 ms 10.494 ms 10.510 ms]
       thrpt:  [92.919 KiB/s 93.055 KiB/s 93.187 KiB/s]
change:
       time:   [-0.2921% -0.0726% +0.1285%] (p = 0.49 > 0.05)
       thrpt:  [-0.1283% +0.0727% +0.2930%]
       No change in performance detected.
streams/walltime/1000-streams/each-1000-bytes: Change within noise threshold.
       time:   [34.129 ms 34.164 ms 34.199 ms]
       thrpt:  [27.886 MiB/s 27.915 MiB/s 27.944 MiB/s]
change:
       time:   [+1.0731% +1.2256% +1.3863%] (p = 0.00 < 0.05)
       thrpt:  [-1.3674% -1.2107% -1.0617%]
       Change within noise threshold.
streams-flow-controlled/walltime/1-streams/each-4194304-bytes: Change within noise threshold.
       time:   [25.860 ms 25.892 ms 25.924 ms]
       thrpt:  [154.29 MiB/s 154.49 MiB/s 154.68 MiB/s]
change:
       time:   [+1.5826% +1.7700% +1.9548%] (p = 0.00 < 0.05)
       thrpt:  [-1.9174% -1.7392% -1.5580%]
       Change within noise threshold.
streams-flow-controlled/walltime/10-streams/each-1048576-bytes: Change within noise threshold.
       time:   [71.571 ms 71.649 ms 71.728 ms]
       thrpt:  [139.42 MiB/s 139.57 MiB/s 139.72 MiB/s]
change:
       time:   [+1.0602% +1.2188% +1.3824%] (p = 0.00 < 0.05)
       thrpt:  [-1.3635% -1.2041% -1.0491%]
       Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
transfer/walltime/pacing-false/varying-seeds: Change within noise threshold.
       time:   [17.513 ms 17.526 ms 17.538 ms]
       thrpt:  [228.07 MiB/s 228.24 MiB/s 228.40 MiB/s]
change:
       time:   [+0.6748% +0.7704% +0.8709%] (p = 0.00 < 0.05)
       thrpt:  [-0.8634% -0.7645% -0.6702%]
       Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
transfer/walltime/pacing-true/varying-seeds: Change within noise threshold.
       time:   [17.799 ms 17.810 ms 17.820 ms]
       thrpt:  [224.46 MiB/s 224.60 MiB/s 224.73 MiB/s]
change:
       time:   [+0.0190% +0.1157% +0.2119%] (p = 0.02 < 0.05)
       thrpt:  [-0.2114% -0.1155% -0.0190%]
       Change within noise threshold.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
transfer/walltime/pacing-false/same-seed: Change within noise threshold.
       time:   [17.442 ms 17.455 ms 17.467 ms]
       thrpt:  [229.00 MiB/s 229.16 MiB/s 229.33 MiB/s]
change:
       time:   [+0.3058% +0.3880% +0.4811%] (p = 0.00 < 0.05)
       thrpt:  [-0.4788% -0.3865% -0.3049%]
       Change within noise threshold.
transfer/walltime/pacing-true/same-seed: Change within noise threshold.
       time:   [17.968 ms 17.978 ms 17.988 ms]
       thrpt:  [222.37 MiB/s 222.49 MiB/s 222.62 MiB/s]
change:
       time:   [+1.2666% +1.3460% +1.4251%] (p = 0.00 < 0.05)
       thrpt:  [-1.4051% -1.3281% -1.2508%]
       Change within noise threshold.
Found 4 outliers among 100 measurements (4.00%)
3 (3.00%) low mild
1 (1.00%) high mild

Instructions per cycle

Criterion reported no significant timing changes.

All benchmarks
Benchmark IPC before IPC after ΔIPC
transfer/walltime/pacing-true/varying-seeds 2.23 2.20 -1.1%
transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1504 1.77 1.79 +1.0%
transfer/walltime/pacing-false/varying-seeds 2.23 2.21 -1.0%
transfer/walltime/pacing-false/same-seed 2.24 2.22 -0.8%
transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1504 2.26 2.28 +0.7%
streams-flow-controlled/walltime/1-streams/each-4194304-bytes 2.20 2.19 -0.7%
streams/walltime/1000-streams/each-1-bytes 2.12 2.13 +0.6%
streams/walltime/1-streams/each-1000-bytes 1.83 1.84 +0.6%
transfer/1-conn/1-100mb-req (aka. Upload)/mtu-1504 2.23 2.22 -0.5%
streams-flow-controlled/walltime/10-streams/each-1048576-bytes 2.24 2.24 -0.3%
transfer/walltime/pacing-true/same-seed 2.22 2.21 -0.2%
transfer/1-conn/1-1b-resp (aka. HPS)/mtu-1504 1.82 1.82 +0.0%
streams/walltime/1000-streams/each-1000-bytes 1.93 1.93 -0.0%

Download data for profiler.firefox.com or download performance comparison data.

@github-actions

Copy link
Copy Markdown
Contributor

Client/server transfer results

Performance differences relative to bab27a4.

Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.

Client vs. server Mean±σ Min–Max Median±MAD MiB/s±σ ΔMedian
neqo-neqo-newreno 61.8 ± 2.4 57.8 – 67.8 61.9 ± 2.6 517.8 ± 20.3 💔 +1.3 (+2.2%)
neqo-neqo-newreno-nopacing 61.0 ± 3.3 51.1 – 72.4 60.6 ± 2.8 524.7 ± 28.0 💚 -1.5 (-2.3%)
neqo-s2n-cubic 131.0 ± 2.6 122.7 – 136.4 131.0 ± 2.3 244.2 ± 4.8 💚 -1.6 (-1.2%)

Table above only shows statistically significant changes. See all results below.

All results

Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.

Client vs. server Mean±σ Min–Max Median±MAD MiB/s±σ ΔMedian
google-google 456.7 ± 2.7 448.5 – 465.2 456.2 ± 2.3 70.1 ± 0.4
google-neqo-cubic 264.3 ± 3.2 259.2 – 276.4 263.0 ± 1.9 121.1 ± 1.5 +0.2 (+0.1%)
neqo-google-cubic 645.9 ± 3.0 639.7 – 654.5 645.8 ± 3.2 49.5 ± 0.2 -0.6 (-0.1%)
neqo-neqo-cubic 62.1 ± 3.0 51.6 – 72.7 62.2 ± 1.9 515.4 ± 25.2 +0.4 (+0.6%)
neqo-neqo-cubic-nopacing 60.8 ± 2.5 57.1 – 69.9 60.4 ± 2.6 526.2 ± 22.0 +0.4 (+0.7%)
neqo-neqo-newreno 61.8 ± 2.4 57.8 – 67.8 61.9 ± 2.6 517.8 ± 20.3 💔 +1.3 (+2.2%)
neqo-neqo-newreno-nopacing 61.0 ± 3.3 51.1 – 72.4 60.6 ± 2.8 524.7 ± 28.0 💚 -1.5 (-2.3%)
neqo-quiche-cubic 110.4 ± 3.1 100.5 – 117.1 110.5 ± 2.1 289.9 ± 8.2 +0.2 (+0.1%)
neqo-s2n-cubic 131.0 ± 2.6 122.7 – 136.4 131.0 ± 2.3 244.2 ± 4.8 💚 -1.6 (-1.2%)
quiche-neqo-cubic 134.0 ± 1.8 130.5 – 139.9 133.8 ± 1.8 238.9 ± 3.2 +1.3 (+1.0%)
quiche-quiche 133.8 ± 3.3 127.0 – 141.4 134.1 ± 3.3 239.2 ± 6.0
s2n-neqo-cubic 213.0 ± 2.8 209.2 – 222.7 212.1 ± 1.9 150.2 ± 2.0 -0.6 (-0.3%)
s2n-s2n ⚠️ 287.6 ± 21.9 277.0 – 382.8 282.3 ± 2.6 111.3 ± 8.5

Download data for profiler.firefox.com or download performance comparison data.

DatagramQueue holds one session's outgoing datagrams: round-robin between
send groups (equal turns, not equal bytes), highest send_order first within
a group, max-age expiry inclusive at timestamp + max_age, and a byte budget
that evicts the lowest-priority datagram rather than the newest. enqueue
reports Ok/AboveWatermark/Rejected/Overflowed, and anything but Ok arms the
resume signal resume_if_unblocked reports once the queue drains back below
the high water mark - by a send or by expiry.

DatagramQueue is exported only so this commit's lib target has a live user;
the next one, which gives QuicDatagrams a queue per session, takes the
export back out.
New Connection methods: enqueue_datagram, set_datagram_high_water_mark,
set_datagram_max_age, datagram_queue_capacity, drop_session_datagrams.
QuicDatagrams gains a BTreeMap<StreamId, DatagramQueue> and
round-robins across sessions in write_frames one datagram at a time,
so a datagram that doesn't fit is left queued (with its original
timestamp) rather than round-tripped back through enqueue.

Hooks the datagram-expiry deadline into next_delay and expiry itself
into process_timer, the same way every other subsystem's timer works.
Expiry - on the timer or from a shrunken max age - also fires
OutgoingDatagramSpaceAvailable for any queue it unblocks: shedding by age
is how one of these queues is expected to drain, and nothing else would
ever revisit a queue that emptied without sending.

The caller, not this layer, has to keep what it enqueues within the peer's
max_datagram_frame_size: only the path MTU is applied at packet-build time.
send_datagram is the checked path.

QuicDatagrams also keeps a simpler count-bounded queue
(send_datagram/remaining_datagram_queue_capacity) for callers that
don't need per-session tracking, priority, or age.
…unts

process_timer's own sweep already expires every session's queue on
its own schedule but discards the result. This gives a caller (the
HTTP3 layer) a way to run that same sweep on demand and get the
expired IDs back, to report a per-datagram outcome.

expire_session_datagrams is the same thing for one session. A caller
holding a single session cannot tell which of a connection-wide sweep's
IDs were its own, and a connection can carry several extended-CONNECT
sessions at once.
Send datagrams through the new per-session queue instead of the legacy
connection-wide FIFO, for both WebTransport and connect-udp, so
send_datagram reports real backpressure and each session's queue is
expired and torn down along with it.

Tests cover send-order priority and byte-budget eviction through a live
WebTransport connection, and that the queue's resume signal still reaches
Http3ServerEvent::OutgoingDatagramSpaceAvailable.  connect-udp has no
outgoingHighWaterMark equivalent, so its old resume-signal test is renamed
to what it now checks.
Connection::send_datagram, QuicDatagrams::add_datagram/datagrams/
max_queued_outgoing_datagrams, and ConnectionParameters::
outgoing_datagram_queue only ever had one production caller,
Session::send_datagram, and that switched to the per-session
enqueue_datagram queue in the previous commit. Firefox's WebTransport
and MASQUE connect-udp stacks are the only two QUIC-datagram users,
and both now go exclusively through the per-session path, so the
plain, count-bounded FIFO has no caller left.

connection/tests/datagram.rs: dropped the tests exercising the
count-bounded queue's own backpressure contract (Ok(true)/Ok(false),
blocking/resuming on a fixed slot count) - the per-session queue's own
byte-budget/high-water-mark backpressure already has equivalent
coverage further down in this file. Ported the tests exercising
protocol-level mechanics that have no other coverage (frame encoding,
ack/loss recovery tokens, stream/datagram priority interleaving,
MTU-drop, packet-fill-gap edge cases) to enqueue_datagram instead.

Requested by mxinden on PR 3984.
Implements Protocol::record_expired_outgoing_datagrams on the WebTransport
session, so SessionStats::datagrams_expired_outgoing actually increments;
the field existed but was hardcoded to stay zero, per its own doc comment
("populated once datagram expiry is wired up").

The test that checks it is also the first caller of the three test-only
ServerSession accessors added with the queues, so their #[expect(dead_code)]
markers come off here.

The sweep that produces those expiries runs from process_http3 on both the
client and server, added in the previous commit alongside the queues it
sweeps.
Connection::next_datagram_expiry() is a live query onto the same queue
next_delay/process_timer already read, exposed so a caller can ask
'is anything due right now' independently of process_output's own
callback-driven schedule.

Http3ServerHandler::should_be_processed uses it: without this check, a
server connection with nothing else pending never gets process_http3
called, so its per-session expiry sweep (stats, and any future outcome
reporting) never runs for a datagram that goes stale with nothing else
happening on the connection. process_timer still expires it either way
- nothing gets sent late - but the http3-level bookkeeping for it was
silently lost. Gated on the session being active, since a connection
that has stopped being processed can't refresh a stale deadline, and an
unguarded check would then return true forever.

The client has no equivalent gap: Http3Client::process_http3 already
runs unconditionally on every process_output call.
@jesup
jesup force-pushed the users/jesup/process_when_only_a_datagram branch from 07ad55d to 49a9494 Compare September 23, 2026 06:27
@jesup
jesup changed the base branch from users/jesup/watermark_priority_eviction to users/jesup/expire_datagrams September 23, 2026 06:27
@jesup
jesup force-pushed the users/jesup/expire_datagrams branch from bcd4abd to 325e0d2 Compare September 23, 2026 23:55
@jesup
jesup force-pushed the users/jesup/expire_datagrams branch 6 times, most recently from a0174a1 to 40e8b3a Compare September 29, 2026 14:51
@jesup jesup closed this Sep 30, 2026
@jesup
jesup deleted the users/jesup/process_when_only_a_datagram branch September 30, 2026 03:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants