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

Introduce biased argument for select! #3603

Merged
merged 7 commits into from Mar 12, 2021

Conversation

lilymara-onesignal
Copy link
Contributor

@lilymara-onesignal lilymara-onesignal commented Mar 10, 2021

Similar to futures::select_biased!, it is sometimes beneficial to
provide developers with strict control over the polling order of
futures. Most of the time, the fairness guarantees that select!
provides through RNG can be thought out by a careful developer to ensure
that no one future will monopolize all of the CPU time. In exchange for
this, the developer gets a performance boost as they do not need to
spend time generating endless random numbers.

Fixes: #2181

Motivation

I want to control future polling order - both for more determinism and to decrease CPU burden from generating random numbers.

Solution

By adding a biased; argument to select!, we can disable the RNG that select performs by default. If this is omitted, we continue to do RNG and behavior is unchanged.

Alternatives

There are a myriad of syntax choices that can be taken to activate this code path. There's a bit of discussion in the linked issue, but I can summarize here.

  • A separate select_biased! macro could be introduced, but Carl is against this
  • Instead of biased, we could allow developers to include the index to start polling at directly. I'm against this because it would make the polling order very hard to understand. As-is, you can read from top to bottom and not worry about skipping around, very straightforward.
  • There are literally an infinite number of tokens that could be used to control this behavior in the macro. I really have no strong opinions, I just picked biased; because it matches with select_biased! from futures. If others have alternatives that are more clear, I'm very open to changing this.

Nate Mara added 2 commits March 10, 2021 12:45
Similar to `futures::select_biased!`, it is sometimes beneficial to
provide developers with strict control over the polling order of
futures. Most of the time, the fairness guarantees that `select!`
provides through RNG can be thought out by a careful developer to ensure
that no one future will monopolize all of the CPU time. In exchange for
this, the developer gets a performance boost as they do not need to
spend time generating endless random numbers.

Fixes: tokio-rs#2181
@Darksonn Darksonn added A-tokio Area: The main tokio crate M-macros Module: macros in the main Tokio crate labels Mar 10, 2021
$crate::select!(@{ () } $p = $($t)*)
// Randomly generate a starting point. This makes `select!` a bit more
// fair and avoids always polling the first future.
$crate::select!(@{ start={ $crate::macros::support::thread_rng_n(BRANCHES) }; () } $p = $($t)*)
Copy link
Contributor

Choose a reason for hiding this comment

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

Huh, it surprises me that we can access BRANCHES 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.

It surprised me too, but I was very happy that my intuition that we couldn't was wrong 😄

@Darksonn
Copy link
Contributor

I think the PR looks reasonable, and this is a feature I want. To me, the main question is the syntax choice.

@carllerche
Copy link
Member

LGTM, but could we add some tests to tests/macros_select.rs?

@carllerche
Copy link
Member

Besides that, it's a very well documented PR. I appreciate the detailed description. Thanks!

@hawkw
Copy link
Member

hawkw commented Mar 11, 2021

This is really nice to have — our codebase mainly uses tokio's select!, but we have a few uses of the futures version specifically to get select_biased!, and it would be really nice to be able to use tokio's everywhere.

@lilymara-onesignal
Copy link
Contributor Author

@carllerche thanks for the review, but what additional test coverage are you looking for? I added the doc test on the polling order because I saw that doc comments are preferred in the contributor guide, and I think what's tested here is really the only novel difference with the normal select! code.

@Darksonn
Copy link
Contributor

It would probably be nice with a test where the select! is not immediately ready.

@carllerche
Copy link
Member

@Darksonn feel free to merge this if/when you feel it is ready.

Copy link
Contributor

@Darksonn Darksonn left a comment

Choose a reason for hiding this comment

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

This looks good to me. 👍

@Darksonn Darksonn merged commit b75d02a into tokio-rs:master Mar 12, 2021
@lilymara-onesignal lilymara-onesignal deleted the select-biased branch March 12, 2021 20:20
@lilymara-onesignal
Copy link
Contributor Author

Thank you @Darksonn and @carllerche! 🎉

/// are always ready.
///
/// This behavior can be overridden by adding `biased;` to the beginning of the
/// macro usage. See the exmples for details. This will cause `select` to poll

Choose a reason for hiding this comment

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

Nit: "examples" (typo)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate M-macros Module: macros in the main Tokio crate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Provide a select_biased! macro
5 participants