Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make async spawn take a closure #1072

Open
NawfelBgh opened this issue Feb 15, 2024 · 3 comments
Open

Make async spawn take a closure #1072

NawfelBgh opened this issue Feb 15, 2024 · 3 comments

Comments

@NawfelBgh
Copy link

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?

@Fishrock123
Copy link
Member

What is the backwards compatibility story on this?

@NawfelBgh
Copy link
Author

NawfelBgh commented Mar 24, 2024

@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

@Fishrock123
Copy link
Member

Fishrock123 commented Apr 10, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants