-
Notifications
You must be signed in to change notification settings - Fork 261
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 broken parallelism in quic-client #2526
Fix broken parallelism in quic-client #2526
Conversation
f6dd865
to
12e9caf
Compare
Let's hold off on merging this until we've gathered some benchmarks. I suggest
For each test, I'll attach bench-tps reported counters and fragmentation rates (depends on #2539). @lijunwangs @alessandrod Can you think of any other tests or datapoints we'd need? |
send_stream.write_all(data).await?; | ||
send_stream.finish().await?; | ||
// Finish sending this stream before sending any new stream | ||
_ = send_stream.set_priority(1000); |
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.
We should probably report the bug that requires this priority hack to the quinn maintainers.
There shouldn't be any reordering in a simple loop like this:
loop {
let mut send_stream = connection.open_uni().await?;
send_stream.write_all(some_buffer()).await?;
}
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 is this needed?
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 looks good, just wondering why the set_priority thing is needed
send_stream.write_all(data).await?; | ||
send_stream.finish().await?; | ||
// Finish sending this stream before sending any new stream | ||
_ = send_stream.set_priority(1000); |
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 is this needed?
@alessandrod It's a workaround for a quinn bug. If you do this you get reordering much worse than the parallel send method before this patch. loop {
let mut send_stream = connection.open_uni().await?;
send_stream.write_all(data).await?;
} I suspect the reason is that the Here is a writeup on the issue: Firedancer-2024-08-10 solana-quic-client fragmentation-110824-162447.pdf |
Fixes excessive fragmentation by TPU clients leading to a large number of streams per conn in 'sending' state simultaneously. This, in turn, requires excessive in-memory buffering server-side to reassemble fragmented transactions. - Simplifies QuicClient::send_batch to enqueue send operations in sequential order - Removes the "max_parallel_streams" config option The quic-client now produces an ordered fragment stream when scheduling send operations from a single-thread.
12e9caf
to
204657f
Compare
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 have rebased this and removed set_priority since I'm not seeing the issue @ripatel-fd was seeing on fd. The PR is obviously correct. I've been doing all my testing in the last month with similar code (no parallel streams).
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.
Tests need work, I'll fixup
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.
ok good to go now
Can you show some of the results of testing with/without the changes? |
I'm using similar code for quite some time, see #2905 and it respects flow control properly (while multistream doesn't not).
In this case the connection will be limited by
Well, what is sensitive to latency is our server side because we fix RW to |
Backports to the stable branch are to be avoided unless absolutely necessary for fixing bugs, security issues, and perf regressions. Changes intended for backport should be structured such that a minimum effective diff can be committed separately from any refactoring, plumbing, cleanup, etc that are not strictly necessary to achieve the goal. Any of the latter should go only into master and ride the normal stabilization schedule. |
* Fix broken parallelism in quic-client Fixes excessive fragmentation by TPU clients leading to a large number of streams per conn in 'sending' state simultaneously. This, in turn, requires excessive in-memory buffering server-side to reassemble fragmented transactions. - Simplifies QuicClient::send_batch to enqueue send operations in sequential order - Removes the "max_parallel_streams" config option The quic-client now produces an ordered fragment stream when scheduling send operations from a single-thread. * quic-client: remove outdated test --------- Co-authored-by: Richard Patel <[email protected]> Co-authored-by: Alessandro Decina <[email protected]> (cherry picked from commit 76cbf1a)
Fix broken parallelism in quic-client (#2526) * Fix broken parallelism in quic-client Fixes excessive fragmentation by TPU clients leading to a large number of streams per conn in 'sending' state simultaneously. This, in turn, requires excessive in-memory buffering server-side to reassemble fragmented transactions. - Simplifies QuicClient::send_batch to enqueue send operations in sequential order - Removes the "max_parallel_streams" config option The quic-client now produces an ordered fragment stream when scheduling send operations from a single-thread. * quic-client: remove outdated test --------- Co-authored-by: Richard Patel <[email protected]> Co-authored-by: Alessandro Decina <[email protected]> (cherry picked from commit 76cbf1a) Co-authored-by: ripatel-fd <[email protected]>
* Fix broken parallelism in quic-client Fixes excessive fragmentation by TPU clients leading to a large number of streams per conn in 'sending' state simultaneously. This, in turn, requires excessive in-memory buffering server-side to reassemble fragmented transactions. - Simplifies QuicClient::send_batch to enqueue send operations in sequential order - Removes the "max_parallel_streams" config option The quic-client now produces an ordered fragment stream when scheduling send operations from a single-thread. * quic-client: remove outdated test --------- Co-authored-by: Richard Patel <[email protected]> Co-authored-by: Alessandro Decina <[email protected]>
Fixes excessive fragmentation by TPU clients leading to a large
number of streams per conn in 'sending' state simultaneously.
This, in turn, requires excessive in-memory buffering server-side
to reassemble fragmented transactions.
in sequential order
The quic-client now produces an ordered fragment stream when
scheduling send operations from a single-thread.