Dominick Pastore
Dominick Pastore

Reputation: 4435

How to run blocking code from async code that borrows?

It's well known that async code should not run for long between awaits. Nonetheless, sometimes async code needs to perform long-running operations, like blocking IO. In those cases, it seems the usual recommendation is to use tokio::task::spawn_blocking (for example, see this blog post from one of the Tokio developers).

The trouble is, as with regular tokio::task::spawn, spawn_blocking must own all the data it accesses (or it must have 'static lifetime), even when immediately awaiting it (see Why does `tokio::spawn` requires a `'static` lifetime if I immediately await it?).

As a result, code like this will not compile:

fn foo(my_ref: &ExpensiveToClone) {
    // Do some stuff that blocks for IO
}

async fn foo_the_reference(my_ref: &ExpensiveToClone) {
    spawn_blocking(move || {
        foo(my_ref);
    }).await;
}

Is there a way to run blocking code from async code without this static lifetime restriction?

Upvotes: 2

Views: 2231

Answers (1)

kmdreko
kmdreko

Reputation: 60493

If using tokio, you can use tokio::task::block_in_place. It still blocks the thread, but it at least notifies the executor that it will be blocked and should offload its tasks to other threads.

Upvotes: 2

Related Questions