Search code examples
rustasync-awaitinfinite-loop

Is it possible to write an asynchronous loop inside synchronous function?


This is my current Rust code

async fn test() {
    ........
    loop {
        ......
        set_timeout(Duration::from_secs(5)).await;
    }
}

I want to make my function synchronous, can I do something like ...

fn test() {
    loop {
        async {
            ......
            set_timeout(Duration::from_secs(5)).await;
        }
    }
}

I tried something as shown above, I removed async keyword from the function and created an async block inside loop, but after this changes, my code somehow becomes unreachable,

How can I keep my "test" function synchronous and still make my code reachable?!


Solution

  • The code with the async block is unreachable since an async block does not execute the code inside, rather it creates a future that when will be .awaited will execute the code inside.

    To execute an asynchronous code inside a synchronous function you need to block. The functions for that are usually provided by the async runtime you use. For example, tokio has block_on() (and a bunch of other functions). You do it like:

    tokio::runtime::Runtime::new().unwrap().handle().block_on(async {
        // ...
    });
    // Or by re-using the current runtime, if you have an active one:
    tokio::runtime::Handle::current().block_on(async {
        // ...
    });
    

    There is a runtime-agnostic block_on() function provided by the futures crate, although using it is likely to be less performant and/or interfere with the runtime.

    Note that blocking while you're executing asynchronous code (if the outer function is called by async code) is bad and may have serious implications.