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

Provide a select_biased! macro #2181

Closed
ifc2t opened this issue Jan 27, 2020 · 3 comments · Fixed by #3603
Closed

Provide a select_biased! macro #2181

ifc2t opened this issue Jan 27, 2020 · 3 comments · Fixed by #3603
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. M-macros Module: macros in the main Tokio crate

Comments

@ifc2t
Copy link

ifc2t commented Jan 27, 2020

Since #2152 introduced the select! macro, is it possible to provide a select_biased! macro as well, similar to the futures-rs one?

It's useful in cases where the polling order does matter, such as when you need to guarantee dropping a future at the next yield point.

@taiki-e taiki-e added A-tokio-macros Area: The tokio-macros crate C-feature-request Category: A feature request. labels Jun 12, 2020
@Darksonn Darksonn added A-tokio Area: The main tokio crate A-tokio-macros Area: The tokio-macros crate M-macros Module: macros in the main Tokio crate and removed A-tokio-macros Area: The tokio-macros crate labels Jul 25, 2020
@Darksonn
Copy link
Contributor

I'm not sure adding a new macro makes sense, but we could add a @bias token or similar?

@carllerche
Copy link
Member

I agree that there are use cases for controlling the poll order. However, I don't love the idea of having a separate macro for the use case.

I wonder if there is a way to work this into the select! macro itself. Maybe some way to annotate branches at the start as prioritized or something...

@qm3ster
Copy link
Contributor

qm3ster commented Feb 5, 2021

Henlo. I was having this whole experience today, and here is what I learned:
The amazing and superior tokio::select! macro actually runs in order, it just selects a starting point with some kind of vendored pseudorandom generator, as follows:

let start = $crate::macros::support::thread_rng_n(BRANCHES);

for i in 0..BRANCHES {
    let branch;
    #[allow(clippy::modulo_one)]
    {
        branch = (start + i) % BRANCHES;
    }

I propose that we move all of the current implementation into a (possibly public? maybe later?) select_starting_at! macro that takes an additional expression to initialize start.

From there, we can reimplement select! to call that with $crate::macros::support::thread_rng_n(BRANCHES); and add select_biased! that just uses 0, thus achieving complete code reuse.

Regarding special annotations on the arms, the current for-based design already doesn't allow patterns like "poll A then C then B then D", so for "always poll A first, then B,C,D in random order" it would have to be changed completely.

Declaration order is a well-understood pattern, and crazy patterns can be achieved with nested selects, if desirable.

lilymara-onesignal pushed a commit to OneSignal/tokio that referenced this issue 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: tokio-rs#2181
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 C-feature-request Category: A feature request. M-macros Module: macros in the main Tokio crate
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants