-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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
Limit initial window size increases and per-stream window delta #26342
Conversation
… of active streams
@@ -309,7 +309,7 @@ class TransportFlowControl final : public TransportFlowControlBase { | |||
return action; | |||
} | |||
|
|||
const grpc_chttp2_transport* const t_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Iirc it's because grpc_chttp2_stream_map_for_each
requires a non-const field. I can probably write a const version of it too though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that would be preferable... just to limit the scope of potential mutations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can track some kind of crude approximation and recheck iff that approximation says we'd overflow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really that much though? Internally, I've seen 100 as the number being thrown around as the configuration for maximum number of concurrent streams?
If it is an issue, we could probably say something like - the initial window size can only grow as much as half the maximum flow control window and a similar restriction on the window delta.
// delta. Min has a ceiling of 0, while max has a floor of 0. | ||
WindowDelta ComputeLocalWindowDeltaBoundaries(grpc_chttp2_transport* t) { | ||
WindowDelta delta; | ||
grpc_chttp2_stream_map_for_each(&t->stream_map, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this change the update from O(1) to O(N)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it does unfortunately. I wonder if there is a way to do this without adding an O(N) loop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder too... as it is this feels a little risky in terms of CPU usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, there is a remaining change that I'm trying to push but running into proxy issues. The change is to do with also limiting stream flow control window updates.
(PS: Thanks for taking a look :))
// delta. Min has a ceiling of 0, while max has a floor of 0. | ||
WindowDelta ComputeLocalWindowDeltaBoundaries(grpc_chttp2_transport* t) { | ||
WindowDelta delta; | ||
grpc_chttp2_stream_map_for_each(&t->stream_map, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it does unfortunately. I wonder if there is a way to do this without adding an O(N) loop
@@ -309,7 +309,7 @@ class TransportFlowControl final : public TransportFlowControlBase { | |||
return action; | |||
} | |||
|
|||
const grpc_chttp2_transport* const t_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Iirc it's because grpc_chttp2_stream_map_for_each
requires a non-const field. I can probably write a const version of it too though
I'm super uncomfortable with expanding this mechanism to become O(n) - especially since doing so will make the flow control mechanism that we use when under duress more expensive. Instead, can I propose we split the flow control windows into two budgets: one for initial window, the other per stream, and we bound each to something extreme but sensible (order 100MB springs to mind, 10MB may be a better default). At that point, we disallow advertising over budget, eliminating the possibility of this condition occuring. |
e9772cb
to
2433674
Compare
@ctiller PTALA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fairly difficult to reason through whether it's correct.
Can you please write a unit test demonstrating that it has the desired behaviors?
86e52a4
to
72022d0
Compare
72022d0
to
f916c41
Compare
Tests added. (There is an internal stress test that helps to verify the behavior too.) |
My memory was that we had an isolated unit test for flow_control.cc, but searching history reveals no such test - perhaps it was started and never completed. I don't think there's any sense in blocking this work on that right now, but it seems this code is ripe for an explicit test that says "if this state changes, this action is performed" so that we can track changes in behavior here. |
Known issues: #26595 |
…#26342) * Limit initial window size increases/decreases by flow control windows of active streams * Limit stream flow control window updates to maximum allowable * Reviewer comments * Alternative way * Clean-up * Add tests * Remove unnecessary cq_verifier * Generate projects * Initialize recv_message * Get around compilation issue * Test size large
…#26342) * Limit initial window size increases/decreases by flow control windows of active streams * Limit stream flow control window updates to maximum allowable * Reviewer comments * Alternative way * Clean-up * Add tests * Remove unnecessary cq_verifier * Generate projects * Initialize recv_message * Get around compilation issue * Test size large
…ta (grpc#26342)" This reverts commit 3e197ac.
…#26342) * Limit initial window size increases/decreases by flow control windows of active streams * Limit stream flow control window updates to maximum allowable * Reviewer comments * Alternative way * Clean-up * Add tests * Remove unnecessary cq_verifier * Generate projects * Initialize recv_message * Get around compilation issue * Test size large
Internal bug reference b/179093825
gRPC Core at present does not consider the flow control windows of existing active streams when sending initial window updates. This can cause flow control windows to go beyond the max limit of 2^31-1 as determined by the HTTP2 spec. This PR fixes that by adding -