tokio_easy_timer/
scheduler.rs

1use chrono::TimeZone;
2
3use crate::extensions::Extensions;
4use crate::job::Job;
5
6pub type BoxedJob<Tz> = Box<dyn Job<Tz> + Send + 'static>;
7pub struct Scheduler<Tz = chrono::Local>
8where
9    Tz: chrono::TimeZone,
10{
11    jobs: Vec<BoxedJob<Tz>>,
12    tz: Tz,
13    extensions: Extensions,
14}
15
16impl Scheduler {
17    /// ## Constructs a new scheduler
18    ///
19    /// the default timezone is chrono::Local, if you want a specified timezone, use `Scheduler::with_tz()` instead.
20    ///
21    /// ### Example
22    ///
23    /// ```rust
24    /// let s = Scheduler::new();
25    /// ```
26    pub fn new() -> Scheduler {
27        Scheduler {
28            extensions: Extensions::default(),
29            jobs: vec![],
30            tz: chrono::Local,
31        }
32    }
33
34    /// if you want a specified timezone instead of the mathine timezone `chrono::Local`, use this
35    pub fn with_tz<Tz: chrono::TimeZone>(tz: Tz) -> Scheduler<Tz> {
36        Scheduler {
37            extensions: Extensions::default(),
38            jobs: vec![],
39            tz,
40        }
41    }
42
43    // pub fn add(mut self, job: BoxedJob) -> Self {
44    //     self.jobs.push(job);
45    //     self
46    // }
47}
48
49impl<Tz> Scheduler<Tz>
50where
51    Tz: TimeZone + Clone + Sync + Send + Copy + 'static,
52    <Tz as TimeZone>::Offset: Send + Sync,
53{
54    /// add a type to the map, you can use it later in the task closer
55    pub fn add_ext<T>(&self, ext: T)
56    where
57        T: 'static + Send + Sync,
58    {
59        self.extensions.insert(ext);
60    }
61
62    /// add a new task to the scheduler, you must privide something that implements `Job` trait.
63    pub fn add(&mut self, job: BoxedJob<Tz>) -> &mut Scheduler<Tz> {
64        self.jobs.push(job);
65        self
66    }
67
68    // pub fn add<Args, F>(&mut self, job: AsyncJob<Args, F>) -> &mut Scheduler<Tz>
69    // where
70    //     Args: Clone + 'static + Send + Sync,
71    //     F: AsyncHandler<Args> + Copy + Send + Sync + 'static,
72    // {
73    //     let job = Box::new(job);
74    //     self.jobs.push(job);
75    //     self
76    // }
77
78    async fn start_spawn(&self) -> &Self {
79        for job in self.jobs.iter() {
80            let e = self.extensions.clone();
81            let tz = self.tz.clone();
82            {
83                let job = job.box_clone();
84                tokio::spawn(async move {
85                    let job = job;
86                    job.start_schedule(e, tz);
87                });
88            }
89        }
90        self
91    }
92
93    /// Start the timer.
94    pub async fn run(&self) -> &Self {
95        self.start_spawn().await
96    }
97
98    /// Start the timer, block the current thread.
99    pub async fn run_pending(&self) {
100        self.start_spawn().await;
101        std::future::pending::<()>().await;
102    }
103}