Flow Control in QUIC: Why do we need an explicit WINDOW_UPDATE for the connection level (ID=0) ?

698 views
Skip to first unread message

Romain Jacotin

unread,
Jun 1, 2015, 6:09:10 AM6/1/15
to proto...@chromium.org
Hello, i dig into the source code to understand the flow control mechanism in QUIC.
It seems that stream and connection share exactly the same flow control algorithm. Are the pictures at the end of this post correct ?

If the connection level flow controller is just an aggregation of all the stream's flow controllers (bytes_consumed = sum of all stream's bytes_consumed, etc...), then why not simply removed the WINDOW_UPDATE communication with stream ID = 0, and just make sure that the MaybeSendWindowUpdate() function doesn't use more than what is currently available at the connection level (=looking at aggregate connection counters how much buffer size is mark as "consumed", so = GetMaxFreeBufferSize() ) ?

Kind regards,
Romain

void QuicFlowController::MaybeSendWindowUpdate() {
  // Send WindowUpdate to increase receive window if
  // (receive window offset - consumed bytes) < (max window / 2).
  // This is behaviour copied from SPDY.
  DCHECK_LT(bytes_consumed_, receive_window_offset_);
  QuicStreamOffset consumed_window = receive_window_offset_ - bytes_consumed_;
  QuicByteCount threshold = (max_receive_window_ / 2);
  if (consumed_window < threshold) {
    // Update our receive window.

    // CURRENT CODE
    // receive_window_offset_ += (max_receive_window_ - consumed_window);

    // NEW CODE
    // receive_window_offset_ += MIN( connection_.GetMaxFreeBufferSize(), (max_receive_window_ - consumed_window) );

    DVLOG(1) << ENDPOINT << "Sending WindowUpdate frame for stream " << id_
             << ", consumed bytes: " << bytes_consumed_
             << ", consumed window: " << consumed_window
             << ", and threshold: " << threshold
             << ", and max recvw: " << max_receive_window_
             << ". New receive window offset is: " << receive_window_offset_;

    // Inform the peer of our new receive window.
    connection_->SendWindowUpdate(id_, receive_window_offset_);
  }


Ryan Hamilton

unread,
Jun 1, 2015, 9:51:44 AM6/1/15
to proto...@chromium.org
QUIC attempts to use the same flow control principles as HTTP/2 does. There are different limits for an individual stream as well as a connection. If we did not have an explicit connection-level WINDOW_UPDATE frame, then and endpoint would be unable increase the size of the per-connection window based on updated information, ala TCP receive window auto tuning, but would instead be stuck with the initial value.

Cheers,

Ryan

--
You received this message because you are subscribed to the Google Groups "QUIC Prototype Protocol Discussion group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to proto-quic+...@chromium.org.
To post to this group, send email to proto...@chromium.org.
For more options, visit https://groups.google.com/a/chromium.org/d/optout.

Romain Jacotin

unread,
Jun 1, 2015, 10:29:07 AM6/1/15
to proto...@chromium.org
Thank you for your reply Ryan. I think it is also a redundant information in HTTP2 specs.

If you protect the global connection buffer size when a stream wants to announce a new WINDOW_UPDATE (like proposed MIN(_,_) function in the post), then you don't need to publish connection level WINDOW_UPDATE.

In fact what i proposed is that it is the receiving stream that make the checks towards the connection level before sending a WINDOW_UPDATE :
  • Can i allocate and send a new WINDOW_UPDATE without violating my connection receive capacity ?
Gain is that we don't need extra-communication for connection WINDOW_UPDATE, and the sender just need to make the following check:
  • Can i send this stream_frame without violating the stream window ?

And what HTTP2 AND QUIC does : the receiving stream and the receiving connection send their own WINDOW_UPDATE information without talking/challenging to each others (????) and it is the responsability of the sender to make TWO checks before sending a stream_frame:
  • Can i send this stream_frame without violating the connection window AND without violating the stream window ?

Ryan Hamilton

unread,
Jun 1, 2015, 1:21:00 PM6/1/15
to proto...@chromium.org
I'm not sure I understand. Let me give some background that you probably already know, to make sure we're on the same page. In each direction (client to server and server to client) the receiver announces, during the handshake, the initial receive windows sizes to be used at the stream and connection levels.  If you look at net-internals when Chrome is speaking QUIC, you'll see that Chrome specifies fairly large windows sizes relative to the server's window size. When a sender wants to send data on a stream, it must verify that the there is available window space at both the stream and connection level. If there is no window available for the particular stream, then sending is prohibited. If there is no window available for the connection, sending is prohibited.  When data is received at the peer, and then handed up to the application, the receiver can send a WINDOW_UPDATE to the sender to allow it to send more.

It may well be the case the over the lifetime of a connection, a receiver may change the amount of data they are willing to receive. For example, they may discover that the link is very fast, and so to ensure that the sender can utilize the full bandwidth, larger limits are appropriate.

Of course, a receiver does not want to sign up for infinite buffering. At the same time, it may way to allow a potentially large number of streams to be in flight at once. So you could imagine a receiver starting with a 1MB limit per stream and a 3MB limit per connection. As the receiver learned more, it might decide that each stream should still be limited to 1MB, but that it is willing to buffer up to 5MB per connection, which is to say, 5 full streams worth of data.

I seems that a per-connection WINDOW_UPDATE messages is required to enact the behavior.

Cheers,

Ryan

--
Reply all
Reply to author
Forward
0 new messages