-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
http3::SendMessage::send_data
can stall
#1819
Comments
mxinden
added a commit
to mxinden/neqo
that referenced
this issue
Apr 16, 2024
Always use up send space on QUIC layer to ensure receiving `ConnectionEvent::SendStreamWritable` event when more send space is available. See mozilla#1819 for details. This commit implements option 2. Fixes mozilla#1819.
mxinden
added a commit
to mxinden/neqo
that referenced
this issue
Apr 16, 2024
Always use up send space on QUIC layer to ensure receiving `ConnectionEvent::SendStreamWritable` event when more send space is available. See mozilla#1819 for details. This commit implements option 2. Fixes mozilla#1819.
mxinden
added a commit
to mxinden/neqo
that referenced
this issue
Apr 17, 2024
Previously `SendMessage::send_data` could stall, if less than the minimum message size is available to be sent. See mozilla#1819 for details. This commit implements solution (3) proposed in mozilla#1819. This commit introduces `SendStream::set_writable_event_low_watermark` which is then used in `SendMessage::send_data` to signal to `SendStream` the minimum required send space (low watermark) for the next send. Once reached, `SendStream` emits a `SendStreamWritable` eventually triggering another `SendMessage::send_data`. Alternative to mozilla#1835. Compared to mozilla#1835, this fix does not utilize the `SendMessage` buffer, thus does not introduce an indirection to the send path. In addition, under the assumption that available send space is increased in larger batches, this fix does not send tiny data frames (2 byte header, 1 byte goodput). Downside, compared to mozilla#1835, is that it requires both changes in `neqo-transport` and `neqo-http3`. Secondarily, this fixes mozilla#1821 as well.
mxinden
added a commit
to mxinden/neqo
that referenced
this issue
Apr 17, 2024
Previously `SendMessage::send_data` could stall, if less than the minimum message size is available to be sent. See mozilla#1819 for details. This commit implements solution (3) proposed in mozilla#1819. This commit introduces `SendStream::set_writable_event_low_watermark` which is then used in `SendMessage::send_data` to signal to `SendStream` the minimum required send space (low watermark) for the next send. Once reached, `SendStream` emits a `SendStreamWritable` eventually triggering another `SendMessage::send_data`. Alternative to mozilla#1835. Compared to mozilla#1835, this fix does not utilize the `SendMessage` buffer, thus does not introduce an indirection to the send path. In addition, under the assumption that available send space is increased in larger batches, this fix does not send tiny data frames (2 byte header, 1 byte goodput). Downside, compared to mozilla#1835, is that it requires both changes in `neqo-transport` and `neqo-http3`. Secondarily, this fixes mozilla#1821 as well.
github-merge-queue bot
pushed a commit
that referenced
this issue
May 7, 2024
…1838) * fix(SendMessage): use SendStream::set_writable_event_low_watermark Previously `SendMessage::send_data` could stall, if less than the minimum message size is available to be sent. See #1819 for details. This commit implements solution (3) proposed in #1819. This commit introduces `SendStream::set_writable_event_low_watermark` which is then used in `SendMessage::send_data` to signal to `SendStream` the minimum required send space (low watermark) for the next send. Once reached, `SendStream` emits a `SendStreamWritable` eventually triggering another `SendMessage::send_data`. Alternative to #1835. Compared to #1835, this fix does not utilize the `SendMessage` buffer, thus does not introduce an indirection to the send path. In addition, under the assumption that available send space is increased in larger batches, this fix does not send tiny data frames (2 byte header, 1 byte goodput). Downside, compared to #1835, is that it requires both changes in `neqo-transport` and `neqo-http3`. Secondarily, this fixes #1821 as well. * Move const * Add documentation * Add SendStream test * Fix intra doc links * Add neqo-http3 test * Replace goodput with payload * Re-trigger benchmarks Let's see whether the "Download" benchmark is consistent. * Rename emit_writable_event to maybe_emit_writable_event * Replace expect with unwrap * Use NonZeroUsize::get * Replace expect with unwrap * %s/Actually sending/Sending * Typo * Have update() return available amount * Document setting once would suffice * Reduce verbosity * fix: drop RefCell mutable borrow early
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Problem
The QUIC layer (
neqo-transport
) notifies the http3 layer (neqo-http3
) when new data can be written to a stream viaConnectionEvent::SendStreamWritable
. For example when the maximum stream data is increased by the remote.neqo/neqo-transport/src/send_stream.rs
Lines 1206 to 1216 in c004359
Note that the event is only emitted in case the stream was previously blocked on the limit, not each time the limit increases.
This event is surfaced through the http3 layer to the user as a
Http3ServerEvent::DataWritable
orHttp3ClientEvent::DataWritable
. The user can then write data to the stream, ultimately callingneqo_http3::SendMessage::send_data
.neqo/neqo-http3/src/send_message.rs
Line 168 in c004359
send_data
will check with the underlyingneqo_transport::SendStream
how much bytes are available to send. To make sure it can send at least a header & a 1 byte payload, it checks that the available bytes are not<=2
.neqo/neqo-http3/src/send_message.rs
Lines 177 to 182 in c004359
If it is
<=2
it returns withOk(0)
, effectively wasting theDataWritable
event.In this case:
neqo_transport::SendStream
has available bytes, even though small (0< available <=2
), and thus is waiting for input fromneqo_http3::SendMessage
. It will not emit moreDataWritable
events e.g. on maximum stream data increase, given that it has data available (even though small0< available <=2
).neqo_http3::SendMessage
is waiting forneqo_transport::SendStream
to have more bytes available, i.e. it is waiting for aDataWritable
event.Thus sending of data on the stream stalls indefinitely.
Potential solutions
DataWritable
event on each increase ofneqo_transport::SendStream::avail()
(connection limit, stream limit,tx_buf
limit).neqo_transport::SendStream
inneqo_http3::SendMessage::send_data
. If it is<=2
, buffer the remaining in the already existingSendMessage::stream
BufferedStream
. Given that theneqo_transport::SendStream
buffer is always used up, newDataWritable
events will be emitted byneqo_transport::SendStream
once more bytes are available to be sent.neqo_transport::SendStream
forneqo_http3::SendMessage
to specifyStreamWritable
event low-watermark (@martinthomson).Related
DataWritable
events would be emitted, which, when timed correctly, would prevent the above.SendStream::send
might stall as well. Does Firefox' WebTransport implementation?The text was updated successfully, but these errors were encountered: