Skip to content
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(sockets): correctly handle pending writes to prevent double write #214

Merged
merged 1 commit into from
Nov 8, 2024

Conversation

Threated
Copy link
Member

@Threated Threated commented Nov 8, 2024

The previous implementation called send on the sink directly without using the SinkWriter adapter to convert it to an AsyncWrite. This meant polling the returned future ourself which seemed to work fine for the majority of cases as it either returned Poll::Ready when we were able to send the item to the underlying io or Poll::Pending when the io was busy matching the expected behavior of the AsyncWrite trait. However there is one other case where the future returned by send might return Poll::Pending which is when it was able to send the data to the io but flushing the underlying io returned Poll::Pending. This is an unfornuate property of the send function which I did not realize when initially implementing it. In pratice this leads to a lot of flushes and in my tests caused the bug that occasionally a packet was sent twice as it has been written to the io but not flushed meansing the future returned Poll::Pending leading to the buffer being sent a second time.

TLDR:
The new implementation uses the SinkWriter which both does not flush on every write and ensures data is written properly.

@Threated Threated requested a review from TKussel November 8, 2024 10:52
Comment on lines +467 to +468
let data: Arc<Vec<_>> = (0..13337).map(|_| {
let mut chunk = vec![0; OsRng.gen_range(1..9999)];
Copy link
Member

Choose a reason for hiding this comment

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

Can you motivate these magic numbers?

Copy link
Member

Choose a reason for hiding this comment

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

They are only in the tests, so not critical

Copy link
Member Author

Choose a reason for hiding this comment

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

9999 because its larger than 8192 which is the default buffer size of tokio::io::copy_bidirectional and 13337 because its a cool number and approximately the number of writes that SEL did in my test case.

@Threated Threated merged commit aa7ce7d into develop Nov 8, 2024
23 of 31 checks passed
@Threated Threated deleted the fix/sockets branch November 8, 2024 11:03
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.

2 participants