Recommended library to run a task "periodically"

I am porting one of my old C++ project to Rust. In this project, I have a function that query system information and return a std::map which I write to a SQLite database. I call this function after N minutes, where N depends on the data returned. I was using boost::fibers. The function usually takes a few seconds, and N is much larger than this value (but having a safety barrier would be nice).

I guess, I want something like this:

pub fn query_system() -> Result<SysInfo> {
    // get system info and write to sqlite db.
    sysinfo  
}

fn main() {
   // query system info after very 60 seconds to begin with.
   s2 = cool_crate::call_after_N_seconds(query_system, 60); // 
   // d work
   // do more work.
   s2.update_interval(90); // now query_system is called every 90 seconds. 
   // do more work 
   // ....
}

I guess, I am looking for a timer pattern. Is this the right way to do it in Rust? Any other recommendation?

boost::fibers is an async runtime. If the single global periodic task is the only thing uses it, running the full-blown async runtime would be unnecessarily heavy (though you can live with it). The direct conversion would involve async runtimes like tokio but as I said you may not need it.

The easiest solution would be to run another thread.

use std::thread;
use std::time::Duration;
use std::sync::Arc;
use std::sync::atomic::{self, AtomicU64};

let interval_sec = Arc::new(AtomicU64::new(60));
let interval2 = Arc::clone(&interval_sec);

thread::spawn(move || loop {
    thread::sleep(Duration::from_secs(interval2.load(atomic::Ordering::SeqCst)));
    // do works
});

interval_sec.store(90, atomic::Ordering::SeqCst);
3 Likes

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.