Sometimes you have to manage multiple timer ticks to execute actions in your program. A solution would be to spawn a task for every interval you need and await a interval future.
#[tokio::main]
async fn main() {
let mut interval1 = tokio::time::interval(std::time::Duration::from_secs(2));
let mut interval2 = tokio::time::interval(std::time::Duration::from_secs(5));
tokio::spawn(async move {
loop {
interval1.tick().await;
println!("tick 1");
}
});
tokio::spawn(async move {
loop {
interval2.tick().await;
println!("tick 2");
}
});
loop {
// do something to not block the whole CPU
}
}
Maybe you have seen the tokio::select! marco. Use it to poll many futures to do their work. This makes it possible for us to progress many futures in one single task.
#[tokio::main]
async fn main() {
let mut interval1 = tokio::time::interval(std::time::Duration::from_secs(2));
let mut interval2 = tokio::time::interval(std::time::Duration::from_secs(5));
loop {
tokio::select! {
_ = interval1.tick() => {
println!("tick 1");
}
_ = interval2.tick() => {
println!("tick 2");
}
}
}
}
Be careful with your work to do in the tick body. Heavy work or blocking execution will block your main task and may bring you behind the interval time so the next tick will fire immediately.