Reputation: 4435
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
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