Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why doesn't a nested await point yield up to tokio::select

I think I’m missing something very basic. My expectation is that when tick.tick() completes and starts the sleep loop, tokio::time::sleep(...).await should yield back to the select statement, allowing longer_tick a chance to complete. But once the shorter tick completes, this gets stuck in the sleep loop, never yielding back to select.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ddb47ab0cd5669def5ea0596803381a8

use std::time::Duration;
use tokio::time::interval;

#[tokio::main]
async fn main() {
    let mut tick = interval(Duration::from_millis(500));
    let mut longer_tick = interval(Duration::from_millis(1000));

    loop {
        tokio::select! {
            _ = longer_tick.tick() => {
                println!("longer tick");
            },
            _ = tick.tick() => {
                println!("sleeping");
                sleep().await;
            },
        }
    }
}

async fn sleep() {
    let mut idx = 0;
    loop {
        let time = idx.min(5);
        println!("Sleeping for {} s", time);
        tokio::time::sleep(Duration::from_secs(time)).await;
        idx += 1;
    }
}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Tokio’s select only waits for the futures in the branch section, not the handler. So the sleep future is not considered when using select!.

Also, per the documentation

Waits on multiple concurrent branches, returning when the first branch completes, cancelling the remaining branches.

When one of the branch completes (the interval‘s in this case), the other branches are cancelled.
Therefore when you are using select, it will only ever execute one of the branch handlers.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading