timer-deque-rs 0.8.0

A OS based timer and timer queue which implements timeout queues of different types.
Documentation
use std::{sync::mpsc::{self, RecvTimeoutError, Sender}, time::Duration};

use timer_deque_rs::{AbsoluteTime, PeriodicTask, PeriodicTaskResult, PeriodicTaskTime, RelativeTime, SyncPeriodicTasks};


#[derive(Debug)]
struct TaskStruct1
{
    a1: u64,
    s: Sender<u64>,
}

impl TaskStruct1
{
    fn new(a1: u64, s: Sender<u64>) -> Self
    {
        return Self{ a1: a1, s };
    }
}

impl PeriodicTask for TaskStruct1
{
    fn exec(&mut self) -> PeriodicTaskResult
    {
        println!("taskstruct1 val: {}", self.a1);

        let _ = self.s.send(self.a1);

        // for demo only, do not use sleep in the exec!!!
        std::thread::sleep(Duration::from_micros(8500));

        return PeriodicTaskResult::Ok;
    }
}

    #[derive(Debug)]
    struct TaskStruct2
    {
        a1: u64,
        s: Sender<u64>,
    }

    impl TaskStruct2
    {
        fn new(a1: u64, s: Sender<u64>) -> Self
        {
            return Self{ a1: a1, s };
        }
    }

    impl PeriodicTask for TaskStruct2
    {
        fn exec(&mut self) -> PeriodicTaskResult
        {
            println!("taskstruct2 val: {}", self.a1);

            self.s.send(self.a1).unwrap();

            // for demo only, do not use sleep in the exec!!!
        std::thread::sleep(Duration::from_micros(7500));

            return PeriodicTaskResult::TaskReSchedule(PeriodicTaskTime::exact_time(AbsoluteTime::now() + RelativeTime::new_time(2, 0)));
        }
    }

fn main()
{
    let s = SyncPeriodicTasks::new(2.try_into().unwrap(), false).unwrap();

    let (send, recv) = mpsc::channel::<u64>();

    let task1 = TaskStruct1::new(0, send.clone());
    let task1_ptt = 
        PeriodicTaskTime::interval(RelativeTime::new_time(1, 0));

    let task1_1 = TaskStruct2::new(12, send.clone());
    let task1_1_ptt = PeriodicTaskTime::interval(RelativeTime::new_time(1, 0));
    


    let task2 = TaskStruct1::new(1, send.clone());
    let task2_ptt = 
        PeriodicTaskTime::interval(RelativeTime::new_time(2, 0));

    let task3 = TaskStruct1::new(2, send.clone());
    let task3_ptt = 
        PeriodicTaskTime::interval(RelativeTime::new_time(0, 500_000_000));

    let task4 = TaskStruct1::new(3, send.clone());
    let task4_ptt = 
        PeriodicTaskTime::interval(RelativeTime::new_time(0, 200_000_000));

    let task4_1 = TaskStruct1::new(33, send.clone());
    let task4_1_ptt = 
        PeriodicTaskTime::interval(RelativeTime::new_time(0, 10_000_300));
    
    let task4_2 = TaskStruct1::new(35, send.clone());
    let task4_2_ptt = 
        PeriodicTaskTime::interval(RelativeTime::new_time(0, 7_000_300));

    let task5 = TaskStruct1::new(4, send.clone());
    let task5_ptt = 
        PeriodicTaskTime::exact_time(AbsoluteTime::now() + RelativeTime::new_time(5, 0));

    let task1_guard = s.add("task1", task1, task1_ptt).unwrap();
    let task1_1_guard = s.add("task1_1", task1_1, task1_1_ptt).unwrap();
    let task2_guard = s.add("task2", task2, task2_ptt).unwrap();
    let task3_guard = s.add("task3", task3, task3_ptt).unwrap();
    let task4_guard = s.add("task4", task4, task4_ptt).unwrap();
    let task4_1_guard = s.add("task4_1", task4_1, task4_1_ptt).unwrap();
    let task4_2_guard = s.add("task4_2", task4_2, task4_2_ptt).unwrap();
    let task5_guard = s.add("task5", task5, task5_ptt).unwrap();


    let end = AbsoluteTime::now() + RelativeTime::new_time(5, 500_000_000);

    // for test purposes
    while AbsoluteTime::now() < end
    {
        match recv.recv_timeout(Duration::from_millis(1))
        {
            Ok(rcv_a) => 
                {},
            Err(RecvTimeoutError::Timeout) => 
                continue,
            Err(e) =>
                panic!("{}", e),
        }

        
    }

    // change time
    task5_guard.reschedule_task(PeriodicTaskTime::exact_time(AbsoluteTime::now() + RelativeTime::new_time(0, 500_000_000))).unwrap();

    let end = AbsoluteTime::now() + RelativeTime::new_time(0, 600_000_000);

    while AbsoluteTime::now() < end
    {
        match recv.recv_timeout(Duration::from_millis(1))
        {
            Ok(rcv_a) => 
                {},
            Err(RecvTimeoutError::Timeout) => 
                continue,
            Err(e) =>
                panic!("{}", e),
        }
    }


    let end = AbsoluteTime::now() + RelativeTime::new_time(2, 1000);

    while AbsoluteTime::now() < end
    {
        match recv.recv_timeout(Duration::from_millis(1))
        {
            Ok(rcv_a) => 
                {},
            Err(RecvTimeoutError::Timeout) => 
                continue,
            Err(e) =>
                panic!("{}", e),
        }
    }


    drop(task1_guard);
    drop(task1_1_guard);
    drop(task2_guard);
    drop(task3_guard);
    drop(task4_guard);
    drop(task4_1_guard);
    drop(task4_2_guard);
    drop(task5_guard);

    while let Ok(_) = recv.recv_timeout(Duration::from_secs(1)) {};
    std::thread::sleep(Duration::from_millis(10));
    return;
}