async-rs / async-std

Async version of the Rust standard library

Home Page:https://async.rs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Make async spawn take a closure

NawfelBgh opened this issue · comments

Hello,

I'm posting this idea to many Rust async runtimes discussion threads in order to push for the alternative design of the task spawn API described by @matklad in https://matklad.github.io/2023/12/10/nsfw.html

// std::thread::spawn
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where
    F: FnOnce() -> T + Send + 'static,
    T: Send + 'static {}

// A hypothetical better async spawn
pub fn spawn<F, Fut>(f: F) -> JoinHandle<Fut::Output>
where
    F: FnOnce() -> Fut + Send + 'static,
    Fut: Future,
    Fut::Output: Send + 'static {}

If you think that this is the right direction for rust to take, I suggest to do the following to arrive at the destination ASAP:

  1. change task spawn definition to one that takes a closure returning a future
  2. Provide a safe executor constructor that pins tasks to threads
  3. Make workstealing executors unsafe to construct... until the language developers "fix" this issue of entangling of Send with OS threads

What do you think?

What is the backwards compatibility story on this?

@Fishrock123 this is not backward compatible with current spawning API. After some discussion on the topic I think that a backward compatible approach is to:

Offer another multithreaded executor that pins tasks to threads. This executor shall use the spawn function proposed by matklad delivering better DX to those of us who do not think that work stealing is essential to handling our workloads (Sometimes it's fine to just distribute tasks at creation time fairly between the worker threads).

The current work stealing executor will still exist with its current clunky not too developer friendly spawn API... until language developers "fix" this issue of entangling of Send with OS threads

Offer another multithreaded executor that pins tasks to threads.

Interestingly, this is an option that CloudFlare's pingora async runtime supports (built on top of tokio).

And their runtime has this comment in the source code:
https://github.com/cloudflare/pingora/blob/acee67f87020ef41267fe475bcc5cbed44782a06/pingora-runtime/src/lib.rs#L15-L24

//! Pingora tokio runtime.
//!
//! Tokio runtime comes in two flavors: a single-threaded runtime
//! and a multi-threaded one which provides work stealing.
//! Benchmark shows that, compared to the single-threaded runtime, the multi-threaded one
//! has some overhead due to its more sophisticated work steal scheduling.
//!
//! This crate provides a third flavor: a multi-threaded runtime without work stealing.
//! This flavor is as efficient as the single-threaded runtime while allows the async
//! program to use multiple cores.