-
-
Notifications
You must be signed in to change notification settings - Fork 290
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
fix: streams awaiting capacity lockout #730
Conversation
This PR changes the the assign-capacity queue to prioritize streams that are send-ready. This is necessary to prevent a lockout when streams aren't able to proceed while waiting for connection capacity, but there is none.
Thank you so so much! I'm wondering, would it be complicated to make a unit test that exercises this? Or maybe one of the reporters would like to try the patch and confirm the problem is gone. |
I tested it on the minimal repro sample provided in the issue, and it seems to be working fine. It also fixes this issue:
I'm currently trying to see if we can make this happen but haven't had the time yet. Hence, the draft status Also, is there any benchmark for hyper at the moment? @seanmonstar |
That's fantastic! For benchmarks, the end_to_end ones are likely best. You can use a |
Can this change result in a situation where new streams that are not Update: Looking at this in more detail I don't think the scenario in the question above can happen. It is still not clear to me what the root cause of the problem is. Do we ever attempt to assign capacity to streams that are not open yet? |
What's happening is that the so here's an example:
I've added a test to demonstrate an extreme case of this: e13adae While 7dec3c2 does prevent a lockout, f1f99e0 is a more complete one @seanmonstar. Haven't had the chance to formally benchmark it (hyper benchmark is broken in my machine somehow), but against the go server it seems fine. |
Thanks for the explanation. I think the changes in f1f99e0 are good. |
I can run the benches. I realized the http2 chunked benchmarks could be re-enabled, once that's done I'll compare them. |
Alright, here's the benchmarks, ran 3 times each: master
patch
|
Looking through the results, the differences look like just noise. Maybe there's a workload that matters that the benchmarks don't catch, but 🤷 . If you concur, we can merge this! |
I didn't work on this, but it does look like noise to me. Some of them are highly variable in both |
I noticed that too. I think the issue is that the benchmarks are going over localhost, which means adaptive window which tries to detect bandwidth will have a horrible time. A cool project to improve the adaptive window option would be to setup some tests using turmoil where we can simulate latency. |
Thank you so much @dswij, excellent debugging work here ❤️ |
Shipped as v0.4.1 :) |
This PR changes the the assign-capacity queue to prioritize streams that are send-ready. This is necessary to prevent a lockout when streams aren't able to proceed while waiting for connection capacity, but there is none. Closes hyperium/hyper#3338
This PR changes the the assign-capacity queue to prioritize streams that are send-ready. This is necessary to prevent a lockout when streams aren't able to proceed while waiting for connection capacity, but there is none. Closes hyperium/hyper#3338 Co-authored-by: dswij <[email protected]>
* Add a setter for header_table_size * Include a test for setting header_table_size * Fix formatting * Switch pseudo header order to mimic chrome * support chrome/okhttp impersonate * deps(http): bump version to v0.2.11 * feat(header): support safari header pseudo order * Send frames based on custom configuration * Revert "deps(http): bump version to v0.2.11" * deps(http): bump version to v0.2.11 * bump version to v0.4.2 * fix: streams awaiting capacity lockout (hyperium#730) (hyperium#734) This PR changes the the assign-capacity queue to prioritize streams that are send-ready. This is necessary to prevent a lockout when streams aren't able to proceed while waiting for connection capacity, but there is none. Closes hyperium/hyper#3338 Co-authored-by: dswij <[email protected]> * streams: limit error resets for misbehaving connections This change causes GOAWAYs to be issued to misbehaving connections which for one reason or another cause us to emit lots of error resets. Error resets are not generally expected from valid implementations anyways. The threshold after which we issue GOAWAYs is tunable, and will default to 1024. * Prepare v0.3.24 * perf: optimize header list size calculations (hyperium#750) This speeds up loading blocks in cases where we have many headers already. * deps(http): v0.2 * Fix header order * Optimize pseudo-header sort * Setting static headers * feat(frame): Passing values to solve pseudo order * Add headers priority * Fix default flag * Project rename to `h2-patch` --------- Co-authored-by: 4JX <[email protected]> Co-authored-by: Sean McArthur <[email protected]> Co-authored-by: dswij <[email protected]> Co-authored-by: Noah Kennedy <[email protected]>
* Add a setter for header_table_size * Include a test for setting header_table_size * Fix formatting * Switch pseudo header order to mimic chrome * support chrome/okhttp impersonate * deps(http): bump version to v0.2.11 * feat(header): support safari header pseudo order * Send frames based on custom configuration * Revert "deps(http): bump version to v0.2.11" This reverts commit 7882ee95b58275200863ce15ece74983ec9c76f3. * deps(http): bump version to v0.2.11 * bump version to v0.4.2 * fix: streams awaiting capacity lockout (hyperium#730) (hyperium#734) This PR changes the the assign-capacity queue to prioritize streams that are send-ready. This is necessary to prevent a lockout when streams aren't able to proceed while waiting for connection capacity, but there is none. Closes hyperium/hyper#3338 Co-authored-by: dswij <[email protected]> * v0.3.23 * streams: limit error resets for misbehaving connections This change causes GOAWAYs to be issued to misbehaving connections which for one reason or another cause us to emit lots of error resets. Error resets are not generally expected from valid implementations anyways. The threshold after which we issue GOAWAYs is tunable, and will default to 1024. * Prepare v0.3.24 * perf: optimize header list size calculations (hyperium#750) This speeds up loading blocks in cases where we have many headers already. * bump version to v 0.4.3 * deps(http): v0.2 * Fix header order * Optimize pseudo-header sort * Setting static headers * feat(frame): Passing values to solve pseudo order * Add headers priority * Fix default flag * Project rename to `h2-patch` --------- Co-authored-by: 4JX <[email protected]> Co-authored-by: Sean McArthur <[email protected]> Co-authored-by: dswij <[email protected]> Co-authored-by: Noah Kennedy <[email protected]>
* v0.3.26 * Rename project to `rh2` * Refactor frame sending custom implementation * Export frame `PseudoOrder` settings * Reduce unnecessary Option packaging * v0.3.27 * fix(frame/headers): Fix error when headers priority is empty * v0.3.29 * feat(frame/headers): Packaging headers pseudo order type (hyperium#8) * feat(frame/settings): Packaging settings type (hyperium#9) * Initialize frame settings order in advance * v0.3.31 * feat(frame): Add unknown_setting frame settings (hyperium#10) * Add unknown_setting patch * Customize all Http Settings order * v0.3.40 * fix(frame): Fix unknown setting encode (hyperium#11) * v0.3.41 * feat: Replace with static settings (hyperium#12) * v0.3.50 * feat: Destructive update, fixed-length array records the setting frame order (hyperium#13) * v0.3.60 * Update README.md * Sync upstream (hyperium#14) * fix: streams awaiting capacity lockout (hyperium#730) (hyperium#734) This PR changes the the assign-capacity queue to prioritize streams that are send-ready. This is necessary to prevent a lockout when streams aren't able to proceed while waiting for connection capacity, but there is none. Closes hyperium/hyper#3338 Co-authored-by: dswij <[email protected]> * v0.3.23 * streams: limit error resets for misbehaving connections This change causes GOAWAYs to be issued to misbehaving connections which for one reason or another cause us to emit lots of error resets. Error resets are not generally expected from valid implementations anyways. The threshold after which we issue GOAWAYs is tunable, and will default to 1024. * Prepare v0.3.24 * perf: optimize header list size calculations (hyperium#750) This speeds up loading blocks in cases where we have many headers already. * v0.3.25 * refactor: cleanup new unused warnings (hyperium#757) * fix: limit number of CONTINUATION frames allowed Calculate the amount of allowed CONTINUATION frames based on other settings. max_header_list_size / max_frame_size That is about how many CONTINUATION frames would be needed to send headers up to the max allowed size. We then multiply by that by a small amount, to allow for implementations that don't perfectly pack into the minimum frames *needed*. In practice, *much* more than that would be a very inefficient peer, or a peer trying to waste resources. See https://seanmonstar.com/blog/hyper-http2-continuation-flood/ for more info. * v0.3.26 * fix: return a WriteZero error if frames cannot be written (hyperium#783) Some operating systems will allow you continually call `write()` on a closed socket, and will return `Ok(0)` instead of an error. This patch checks for a zero write, and instead of looping forever trying to write, returns a proper error. Closes hyperium#781 Co-authored-by: leibeiyi <[email protected]> * lints: fix unexpected cfgs warnings * ci: pin deps for MSRV * ci: pin more deps for MSRV job (hyperium#817) * fix: notify_recv after send_reset() in reset_on_recv_stream_err() to ensure local stream is released properly (hyperium#816) Similar to what have been done in fn send_reset<B>(), we should notify RecvStream that is parked after send_reset(). Co-authored-by: Jiahao Liang <[email protected]> --------- Co-authored-by: Sean McArthur <[email protected]> Co-authored-by: dswij <[email protected]> Co-authored-by: Noah Kennedy <[email protected]> Co-authored-by: beiyi lei <[email protected]> Co-authored-by: leibeiyi <[email protected]> Co-authored-by: Jiahao Liang <[email protected]> * v0.3.61 --------- Co-authored-by: Sean McArthur <[email protected]> Co-authored-by: dswij <[email protected]> Co-authored-by: Noah Kennedy <[email protected]> Co-authored-by: beiyi lei <[email protected]> Co-authored-by: leibeiyi <[email protected]> Co-authored-by: Jiahao Liang <[email protected]>
Fixes hyperium/hyper#3338
This PR changes the the assign-capacity queue to prioritize streams that are send-ready.
This is necessary to prevent a lockout when streams aren't able to proceed while waiting for connection capacity, but there is none.