BUG/MEDIUM: mux-quic: improve streams fairness to prevent early timeout
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 21 Apr 2023 12:48:01 +0000 (14:48 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 26 Apr 2023 15:50:16 +0000 (17:50 +0200)
commit7c5591facbe892eaf8df386aab40ff02c7a58c31
treefeb4acf6ea1c96f47773883e83f26d8998f43aab
parent24962dd1784dd22babc8da09a5fc8769617f89e3
BUG/MEDIUM: mux-quic: improve streams fairness to prevent early timeout

Since the following mentioned patch, a send-list mechanism was
implemented to improve streams priorization on sending.
  commit 20f2a425ffeda2e623aac4c702f4e44b1e122d1d
  MAJOR: mux-quic: rework stream sending priorization

This is done to prevent the same streams to always be used as first ones
on emission. However there is still a flaw on the algorithm. Once put in
the send-list, a streams is not removed until it has sent all of its
content. When a stream transfers a large object, it will remain in the
send-list during all the transfer and will soon monopolize the first
place. the stream does never leave its position until the transfer is
finished and will monopolize the first place. Other streams behind won't
have the opportunity to advance on their own transfers due to a Tx
buffer exhaustion.

This situation is especially problematic if a small timeout client is
used. As some streams won't advance on their transfer for a long period
of time, they will be aborted due to a stream layer timeout client
causing a RESET_STREAM emission.

To fix this, during sending each stream with at least some bytes
transferred from its tx.buf to qc_stream_desc out buffer is put at the
end of the send-list. This ensures that on the next iteration streams
that cannot transfer anything will be used in priority.

This patch improves significantly h2load benchmarks for large objects
with several streams opened in parallel on a single connection. Without
it, errors may be reported by h2load for aborted streams. For example,
this improved the following scenario on a 10mbit/s link with a 10s
timeout client :
  $ ./build/bin/h2load --npn-list h3 -t 1 -c 1 -m 30 -n 30 https://198.18.10.11:20443/?s=500k

This fix may help with the github issue #2004 where chrome browser stop
to use QUIC after receiving RESET_STREAM frames.

This should be backported up to 2.7.
src/mux_quic.c