How to only have background tasks with async runtime?

I'm working on an app that uses an async runtime, e.g. smol, to fire off some I/O-bound tasks with infinite loops as main workload and otherwise does nothing.

My current solution is to spawn the tasks and afterwards non-blockingly sleep forever:

use async_std::task::sleep;
use std::time::Duration;

fn main() {
    smol::block_on(run());
}

// Not quite, but close enough
const ETERNITY: Duration = Duration::from_secs(u64::MAX);

async fn run() {
    // for simplicity using the global executor here
    smol::spawn(task1()).detach();
    smol::spawn(task2()).detach();
    sleep(ETERNITY).await;
}

async fn task1() {
    loop {
        sleep(Duration::from_secs(1)).await;
        println!("Doing some work on task1!");
    }
}

async fn task2() {
    loop {
        sleep(Duration::from_secs(2)).await;
        println!("Doing some work on task2!");
    }
}

This seems to work. Still, I'm new to async programming in Rust:

  • Is there anything wrong with my snippet that will come back to bite me later?
  • Is there a better way to do it?

I don't see any major problems. It would be slightly more efficient/idiomatic to use pending instead of sleep(ETERNITY), but what you have will also work just fine.

If you ever want to add a way to shut down cleanly instead of being killed externally, you could wait on a oneshot channel that acts as a shutdown signal.

3 Likes

Note: We have std::future::pending now.

3 Likes