-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
HTTP2 multiplexed requests get stuck in presence of "slow readers", Stream/Connection window is not being updated #2899
Comments
Thanks for the suggestion. |
In the log I don't see any By the code it seems that the connection receive window is being increased only when some stream has received data and was polled - which I believe is not right since some streams may be polled quite late or not polled at all. |
We hit this issue when multiplexing many grpc streams on a same channel with tonic. The fix for us was to set a very high connection window size, to try to effectively disable http2 connection flow control. @dmitryvk I believe you are correct in that capacity is only released when the stream is polled. According to this post multiple gRPC implementations hit this issue and decided to release capacity more eagerly. However my opinion from reading the http2 rfc is that h2 and hyper are implementing flow control correctly. This is quite a footgun but it seems to be by design in http2. If there is anything hyper can improve in its http2 client defaults to fix this, I believe it would be important to do so, as this bug was quite bad in severity and difficulty to debug. @seanmonstar Sorry for the ping, but any insight here would be appreciated. |
I remember reading that blog post, and feeling the same as you described: it sounds like they're effectively disabling connection-level flow control. That has other problems, as the post itself describes. I don't feel the post sufficiently explains how best to offset them, so I haven't wanted to make this default in hyper. But, a user can effectively do so by setting |
I had an idea (that I had not yet tried to implement): release connection capacity when stream is accepted or polled for the first time. This still provides some sort of backpressure and seems to avoid the issue of slow readers hogging connection window capacity. |
I'm curious to hear more. Are you saying that when the user is first giving the |
Version
hyper 0.14.19
h2 0.3.13
Platform
Fedora 36
Description
We use hyper as a server and as a client in distributed application. Hyper client is configured as
.http2_only(true)
.Some GET requests are getting stuck. Those requests stream large response body (tens of megabytes). Some part of response body is transferred (several megabytes) and then both server and client are stuck with zero bytes being transferred. This only happens with HTTP2 in use.
The following code always reproduces this on my machine:
(note that the constants may be specific for a particular machine and may need tweaking for this to reproduce)
I expected to see this happen:
The program would run to completion and would print:
Instead, this happened:
The program prints the following lines and then does nothing:
In wireshark I see that neither client nor server don't send WINDOW_UPDATE frames during data transfer (except at the connection establishment). I suspect that this is a cause for this behavior.
The text was updated successfully, but these errors were encountered: