`async` for functions spawning tasks?

Hi all,

I have a design question. Assume we have a struct that upon creation spawns an async task, e.g.:

struct Handle(Sender<u32>)

impl Handle {
    fn new() {
        let (rx, tx) = channel();
        tokio::task::spawn(async { 
            while Ok(num) = rx.recv().await {
                println!("Got {}", num);

    fn print(num: u32) { self.0.send(num).ok() }

Now Handle::new() is not a future but it will panic if there is no executor running in the background. Would you declare new() as async to prevent a panic or leave it as a 'normal' function?

It's best to declare functions as async fn to avoid forcing a particular runtime on the callers.

For example, even though I use tokio, I have two runtimes with different configurations, and I choose what goes on which one of them. I don't want any library to call spawn ever.

If you must be spawning things ad-hoc yourself, take a Handle.

I don't understand how declaring it async would help here.

Well, having it async would be a more clear way of expressing 'You need some kind of executor to run this'. However, the more I think about it the less beneficial it seems to be... :sweat_smile:

Well, the way your method is implemented, you need Tokio specifically.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.