Function zng::task::spawn

source ·
pub fn spawn<F>(task: impl IntoFuture<IntoFuture = F>)
where F: Future<Output = ()> + Send + 'static,
Expand description

Spawn a parallel async task, this function is not blocking and the task starts executing immediately.

§Parallel

The task runs in the primary rayon thread-pool, every poll happens inside a call to rayon::spawn.

You can use parallel iterators, join or any of rayon’s utilities inside task to make it multi-threaded, otherwise it will run in a single thread at a time, still not blocking the UI.

The rayon crate is re-exported in task::rayon for convenience and compatibility.

§Async

The task is also a future so you can .await, after each .await the task continues executing in whatever rayon thread is free, so the task should either be doing CPU intensive work or awaiting, blocking IO operations block the thread from being used by other tasks reducing overall performance. You can use wait for IO or blocking operations and for networking you can use any of the async crates, as long as they start their own event reactor.

The task lives inside the Waker when awaiting and inside rayon::spawn when running.

§Examples

fn on_event(&mut self) {
    let (responder, response) = response_var();
    self.sum_response = response;

    task::spawn(async move {
        let r = (0..1000).into_par_iter().map(|i| i * i).sum();

        responder.respond(r);
    });
}

fn on_update(&mut self) {
    if let Some(result) = self.sum_response.rsp_new() {
        println!("sum of squares 0..1000: {result}");   
    }
}

The example uses the rayon parallel iterator to compute a result and uses a response_var to send the result to the UI. The task captures the caller LocalContext so the response variable will set correctly.

Note that this function is the most basic way to spawn a parallel task where you must setup channels to the rest of the app yourself, you can use respond to avoid having to manually set a response, or run to .await the result.

§Panic Handling

If the task panics the panic message is logged as an error, the panic is otherwise ignored.

§Unwind Safety

This function disables the unwind safety validation, meaning that in case of a panic shared data can end-up in an invalid, but still memory safe, state. If you are worried about that only use poisoning mutexes or atomics to mutate shared data or use run_catch to detect a panic or run to propagate a panic.