How can I `fut.await` to run a future in the "background" (execute it but not wait for it)?

Viewed 679

I want to able to start a future running in the background, and not wait for it immediately in the parent function scope.

Something like a dynamic join_all where I can add new futures in a loop to a set, and then pass the set to another function which can .await the whole set (that is already running).

I want to be able to do something like this:

join_all(vec![
    log_arg(&c),
    log_arg(&c)
]).await;

But the issues are:

  • .await starts the future executing, but also waits for it at the current function.
    • How do I start the execution without waiting for it?
  • &c is not 'static
    • Seems to be a requirement for all of the Tokio API's that "start the future executing without waiting for the result in the current fn scope", e.g spawn_local
    • It is OK if all the futures are on a single thread.

Example:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=85aa3a517bd1906b285f5a5586d7fa6d

1 Answers

How do I start the execution without waiting for it?

spawn a task.

Seems to be a requirement for all of the Tokio API's that "start the future executing without waiting for the result in the current fn scope", e.g spawn_local

Well yes, since you're spawning a task it's possible that the task outlives whatever owns the item, resulting in a dangling reference, which is not allowed. In fact it's pretty much a guarantee when using spawn_local: it's going to spawn a task on the same thread (/scheduler), and that will not be able to run at all until the current task yields or terminates.

The alternative would be to use "scoped tasks" (which don't have to be immediately waited on, but have to eventually be joined). However support for structured concurrency (scoped tasks) in tokio have so far died on the vine. So there is no way for the Rust compiler to know that a task does not "escape" from the scope which intiialised it, therefore it has to assume it does, and thus that whatever the task captures should be able to outlive the current scope.

Related