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 select biased by fusing streams outside loop #106

Merged
merged 4 commits into from
Jan 24, 2025
Merged

Conversation

jcdyer
Copy link
Contributor

@jcdyer jcdyer commented Jan 24, 2025

  • Fuse streams properly in select_biased in WebsocketHandle::stream and run_worker.

Based on the documentation for select_biased, as reported by a customer, streams used in select_biased need to be fused on the stream, not the future, and futures polled more than once need to be fused outside the loop. Otherwise, the inner future will need to be re-polled each time to determine whether fusing needs to happen, which causes a busy loop (at best) in the case of Streams, and a possible panic for Futures.

@jcdyer jcdyer self-assigned this Jan 24, 2025
@jcdyer jcdyer requested a review from bd-g January 24, 2025 16:06
let mut is_open: bool = true;
let mut last_sent_message = tokio::time::Instant::now();
let mut message_rx = message_rx.fuse();
Copy link
Contributor

Choose a reason for hiding this comment

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

It won't let me comment on the tokio::time::sleep_until variable a few lines down.

I presume this doesn't need to be fused outside the loop, since the variable is created within the loop, so it isn't subject to the same polling issues as the other futures, which are called repeatedly within the loop?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, since message_rx is fused here, shouldn't we not fuse it within the loop?

It seems like object.next().fuse() can override the object.fuse() call and still cause rough behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct about sleep. Each new iteration of the loop gets a new future, so any given sleep future will not get polled after the single select_biased! construct completes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch on the message_rx.next().fuse(). Fixed in 35b2083

Copy link

@jfoster-twilio jfoster-twilio left a comment

Choose a reason for hiding this comment

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

This is pretty close to what we were testing -- just a couple suggestion on unnecessary .fuse calls

let mut is_open: bool = true;
let mut last_sent_message = tokio::time::Instant::now();
let mut message_rx = message_rx.fuse();

Choose a reason for hiding this comment

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

The message_rx Receiver already implements FusedStream so you don't need to .fuse() it here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, good catch. Removed in 35b2083

@@ -703,7 +706,7 @@ impl WebsocketHandle {

Ok(WebsocketHandle {
message_tx,
response_rx,
response_rx: response_rx.fuse(),

Choose a reason for hiding this comment

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

similar to above -- the response_rx Receiver already implements FusedStream so you don't need to .fuse() it here

@jcdyer jcdyer requested a review from bd-g January 24, 2025 18:14
@jcdyer jcdyer merged commit ad28a9e into main Jan 24, 2025
18 checks passed
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