Implement server::Builder::max_send_buffer_size#577
Conversation
|
I tried using |
f7d388f to
4693e9c
Compare
|
@seanmonstar Do you think h2 should have a default maximum? |
|
Also, do you have any idea how I could write a test for this? |
4693e9c to
30a66ec
Compare
| self.try_assign_capacity(stream); | ||
| } | ||
|
|
||
| self.current_send_buffer_size += sz as usize; |
There was a problem hiding this comment.
I used to do this prior to calling try_assign_capacity. AFAIU that was wrong, right?
There was a problem hiding this comment.
That sounds right. The connection-level and stream-level should be updated together, but since updating the stream-level may make it exceed it's requested capacity and thus needs to check for more capacity, that must happen in-between.
A code comment about the ordering being important may be prudent.
Hm, probably yes. Also, it might be good (once we have it working) to compare how this change affects hyper's http2 |
| tracing::trace_span!("updating stream flow").in_scope(|| { | ||
| stream.send_flow.send_data(len); | ||
|
|
||
| self.current_send_buffer_size -= len as usize; |
There was a problem hiding this comment.
I think this area needs to potentially wake up any tasks that have been waiting on "capacity", since now there is "more buffer space to use". The reason it needs to be done here, is because with flow control capacity, the connection doesn't actually get more until the peer has sent another WINDOW_UPDATE frame. So recv_window_update will notify a task there. But buffer size isn't affected by WINDOW_UPDATE frames.
There was a problem hiding this comment.
I'm not sure I understand. Why do we even call self.flow.assign_capacity(len); below that line, if we are actually supposed to wait for the peer to send another WINDOW_UPDATE frame?
There was a problem hiding this comment.
I am even more confused that we call self.flow.send_data(len); immediately afterwards we called self.flow.assign_capacity(len);.
There was a problem hiding this comment.
Doesn't that mean that self.flow.available never changes from Prioritize::pop_frame? I don't understand the logic there.
There was a problem hiding this comment.
I called assign_connection_capacity from poll_complete after the reclaim_frame call.
30a66ec to
d837e1f
Compare
d837e1f to
acb0041
Compare
tests/h2-tests/tests/flow_control.rs
Outdated
|
|
||
| for _ in 0..3 { | ||
| stream.reserve_capacity(5); | ||
| stream = util::wait_for_capacity(stream, 5).await; |
There was a problem hiding this comment.
The test is hanging there, and by the time h2 returns Poll::Pending, Actions::task is None so there is no way to wake up the connection task to call poll_complete from there.
| t2.await.expect("srv body spawn"); | ||
| t1.await.expect("srv body spawn"); | ||
| t0.await.expect("srv end"); |
There was a problem hiding this comment.
AFAIK the test is still wrong. We await for t2 before we await for t0, so t0 is pending and nothing will wake it up when t2 notifies the connection task that it has frames to send, so the send buffer size never decreases and everything gets stuck.
There was a problem hiding this comment.
Never mind I misread. That being said, the test really doesn't help much finding where the issue with my patch is :/
There was a problem hiding this comment.
h2/tests/h2-support/src/util.rs
Lines 56 to 66 in 2c53d60
There, poll_capacity returns Ready(Some(0)), and capacity returns 0, so act >= self.target is false, and Poll::Pending gets returned even though nothing has been set up to wake up the task.
What do you think is wrong here? That poll_capacity returns Ready(Some(0)), or that wait_for_capacity is badly conceived, or both?
No description provided.