Why do Structs in tokio::spawn blocks need to be Send even when running in single thread mode?

I am running my async program in single threaded mode:

#[tokio::main(flavor = "current_thread")]

But when doing,

let handle = tokio::spawn(async move {
     worker.run(controller);
});

The rust analyzer gives me an error "captured value is not Send".
While I understand the issue in multi-threaded runtime mode, why should this be the case in single-threaded mode?

The function signature of spawn doesn't change if you use a single threaded runtime. You can use a LocalSet to spawn !Send futures on the current thread concurrently.

7 Likes

... or use a single-threaded runtime like Glommio.

1 Like

Thanks for sharing this, but Glommio does not seem to be in active development anymore.

There is also tokio::task::spawn_local().

(Requires the unstable API, and #[tokio::main(flavor = "local")] or LocalRuntime.)

spawn_local also works within the context (::block_on, ::enter or ::run_until) of a LocalSet, not only a LocalRuntime. This is comes in handy if you don't have a reference to the LocalSet instance available, e.g. if you need to spawn a task from deep within your call stack.

There's also monoio which is active, I didn't test it though.