I would like to use Rust to create a simple scheduler in order to run multiple concurrent functions at a defined time but do not start more if they haven't finished.
For example, if the defined interval is one second, the scheduler should run the functions and don't start more if the previous functions have not returned. The goal is to prevent running the same function multiple times.
I created a working example with Go like this:
package main
import (
"fmt"
"sync"
"time"
)
func myFunc(wg *sync.WaitGroup) {
fmt.Printf("now: %+s\n", time.Now())
time.Sleep(3 * time.Second)
wg.Done()
}
func main() {
quit := make(chan bool)
t := time.NewTicker(time.Second)
go func() {
for {
select {
case <-t.C:
var wg sync.WaitGroup
for i := 0; i <= 4; i++ {
wg.Add(1)
go myFunc(&wg)
}
wg.Wait()
fmt.Printf("--- done ---\n\n")
case <-quit:
return
}
}
}()
<-time.After(time.Minute)
close(quit)
}
Since I didn't find something like Go's NewTicker
within the Rust standard library, I used Tokio and came up with this
extern crate futures;
extern crate tokio;
use futures::future::lazy;
use std::{thread, time};
use tokio::prelude::*;
use tokio::timer::Interval;
fn main() {
let task = Interval::new(time::Instant::now(), time::Duration::new(1, 0))
.for_each(|interval| {
println!("Interval: {:?}", interval);
for i in 0..5 {
tokio::spawn(lazy(move || {
println!("I am i: {}", i);
thread::sleep(time::Duration::from_secs(3));
Ok(())
}));
}
Ok(())
})
.map_err(|e| panic!("interval errored; err={:?}", e));
tokio::run(task);
}
The problem I have with this approach is that the tasks don't wait for the previous functions to be called therefore the functions start again no matter if previously they were running, I am missing here something like Go's sync.WaitGroup
. What could be used to achieve the same results as in the working example?
Is it possible to achieve this by only using the standard library? This is mainly for learning purposes, probably there is a pretty straightforward way of doing it and I could avoid extra complexity.
In the end, I would like to periodically monitor some sites via HTTP (get just the returned status code) but don't query all of them again until I have all the responses.