Skip to content

feat: add Connection::set_send_window() #2268

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

abonander
Copy link
Contributor

@abonander abonander commented Jun 17, 2025

We have a desire to limit the amount of bandwidth used for a given peer in both directions, but by the nature of the application, we can't decide that limit is until we're already connected to the peer and have verified their identity.

We already make use of backpressure throughout the application, so we can use the connection itself to limit the bandwidth used without everything backing up elsewhere.

I think we can most easily affect this by setting the receive_window to our desired bandwidth times the RTT, but that only gives us control over inbound bandwidth; we don't currently have a way to set the send_window after the connection is established.

Looking through the implementation, the handling of send_window doesn't look to be nearly as complex as read_window since it's a purely local control knob, so I feel like letting the user set it dynamically shouldn't cause any issues.

I do have a question about how best to test this. I see there's tests for set_receive_window that I can copy, but I've only got an inkling of how the send_window tests should work:

  • Create a stream::State with a set send_window
  • Open and try to write to a stream, observe that it only accepts send_window bytes
  • Increase send_window and see if State::poll() generates a Writable event?

How would I test the shrinkage of send_window? Write N bytes, ack them, set send_window < N and try to write the same amount again?

Copy link
Collaborator

@Ralith Ralith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I think this is well motivated and I don't immediately see any problems with the implementation. Can you add unit tests for growth and shrinking, including verification that StreamWritable events are emitted at the appropriate time?

@abonander
Copy link
Contributor Author

@Ralith if you read the description, I had a question of exactly how those tests should work.

@Ralith
Copy link
Collaborator

Ralith commented Jun 18, 2025

Oops; I had read the email notification which did not contain your edits.

The strategy you outline for testing window growth makes sense to me, though for completeness I would include a step that actually writes into the new space and verifies that the amount of additional data written is as expected. Maybe also verify that increasing the send window above the flow control limit doesn't allow too much data to be written.

How would I test the shrinkage of send_window? Write N bytes, ack them, set send_window < N and try to write the same amount again?

I can think of a couple interesting cases off-hand:

  1. Construct with send window I
  2. Shrink send window to N < I
  3. Attempt to write N bytes, assert that only I can be written

And:

  1. Write to fill the initial send window I
  2. Shrink send window to N < I
  3. Assert that writes are still not accepted
  4. Ack at most (N - I) bytes
  5. Assert that writes are still not accepted
  6. Ack all outstanding data
  7. Assert that exactly N bytes can be written

@djc
Copy link
Member

djc commented Jul 7, 2025

@abonander would you be able to finish this up with a test case?

@abonander
Copy link
Contributor Author

I'll try to when I get some breathing room. Things are a bit hectic at work right now. I'm having to squeeze in SQLx work during my weekend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants