grapeTimerR/
lib.rs

1/*!
2[![made-with-Rust](https://img.shields.io/badge/made%20with-rust-red)](https://www.rust-lang.org/)
3[![Open Source Love svg2](https://badges.frapsoft.com/os/v2/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/)
4[![crates.io](https://img.shields.io/badge/crates.io-grapeTimerR-orange.svg)](https://crates.io/crates/grapeTimerR)
5[![docs.rs](https://img.shields.io/badge/docs-grapeTimerR-blue.svg)](https://docs.rs/grapeTimerR)
6
7## **简介 Intro**
8
9A coarse-grained time scheduler can help you create time tasks quickly and simply through some series.
10
11一款粗粒度的时间调度器,可以帮你通过一些字符串快速并简单的创建时间任务。
12
13grapeTimer的Rust版本,提供相同功能以及相同类型的服务。
14
15## **功能 Feature**
16- 纯异步的代码执行(Pure async code)
17- 通过命令格式创建`std::chrono::Datetime`(Created by date format)
18- 简洁的Api格式,轻度且可拆分的函数库(Simple Api, light and detachable library)
19- 快速创建调度器(Quickly create a scheduler)
20- 可控的调度器时间粒度`[需要提前指定]`(Controllable scheduler time granularity `[Need to specify in advance]`)
21- 多线程调度模式(Multi-thread scheduling mode)
22- 时间周期,次数多模式可控`[支持每天、每周、每月]`(Time period, multi-mode controllable number of times `[support daily, weekly, monthly]`)
23- 可以获取下一次执行时间`[Chrono Datetime]`(Can get the string of the next execution time)
24- 自定义起始TimerId的种子(Customize the seed of the starting TimerId)
25- 自定义TimerId的生成函数`[自生成ID请注意并发场景下的线程争抢]`(Custom TimerId generation trait `[Self-generated ID, please pay attention to thread contention in concurrent scenarios]`)
26- TimerId扩展为i64,支持大ID和timestampId生成器(TimerId is i64, supporting large Id and timestampId generator correspondence)
27
28## **日期格式 Date Format**
29
30The scheduler has a light date pattern analysis system, which can provide daily, weekly, and monthly time and date generation methods
31
32调度器有轻度的日期模式分析体系,可提供每日,每周,每月的时间日期生成方式,具体格式如下:
33
34|关键字 Key|格式 Format |说明 Description|
35|:----------:|:-------:|:----------:|
36|Day|Day 00:00:00|生成每日的日期时间|
37|Week|Week 1 00:00:00|生成每周的日期时间, 0~6 分别代表周日到周六 |
38|Month|Month 1 00:00:00|生成每月该日期的时间,建议不要使用28日之后的日期|
39
40|Key|Format |Description|
41|:----------:|:-------:|:----------:|
42|Day|Day 00:00:00|Generate daily date and time|
43|Week|Week 1 00:00:00|Generate weekly date and time, 0~6 represent Sunday to Saturday|
44|Month|Month 1 00:00:00|The time when the date of the month was generated, it is recommended not to use the date after the 28th|
45*/
46
47pub mod schedule;
48pub mod parsers;
49pub mod errors;
50mod thread;
51mod uuid;
52
53pub use crate::uuid::uuid::IDMode;
54
55pub mod timer {
56    use std::sync::{Mutex,Arc};
57    use std::time;
58    use crate::schedule::schedule;
59    use crate::schedule::schedule::{TaskAction, ClosuresAction};
60    use crate::errors::errors::{TResult, TError, TErrorKind};
61    use crate::IDMode;
62    use lazy_static::*;
63    use crate::thread::threads::{TaskPool};
64    use crate::uuid::uuid::{set_seed, next_timestamp_id, next_big_id};
65    use simple_log;
66    use simple_log::LogConfigBuilder;
67    use std::future::Future;
68
69    #[derive(Clone)]
70    struct InterData {
71        config:Arc<Mutex<Config>>,
72        thread_pool:Arc<Mutex<TaskPool>>,
73    }
74
75    #[derive(Clone)]
76    pub struct Config {
77        pub debug:bool,
78        pub debug_log:String,
79        pub thread_count:i32,
80        pub id_seed:i64, // 起始ID
81        pub id_type:IDMode,
82    }
83
84    lazy_static! {
85        static ref Inter:InterData = InterData{
86           config:Arc::new(Mutex::new(Config{
87                debug:false,
88                debug_log:String::new(),
89                thread_count:4,
90                id_seed:1, // 起始ID
91                id_type:IDMode::SequenceId,
92           })),
93            thread_pool:Arc::new(Mutex::new(TaskPool::new(time::Duration::from_secs(1),4)))
94         };
95    }
96
97    fn next_uuid() -> u64 {
98        match Inter.config.lock().unwrap().id_type {
99            IDMode::SequenceId => { next_big_id() as u64 }
100            IDMode::TimestampId => { next_timestamp_id() as u64 }
101        }
102    }
103
104    /// init schedule system [用于初始化调度系统,通过Config]
105    ///
106    /// # Examples
107    ///
108    /// ```
109    /// use grapeTimerR::{timer::Config,IDMode, timer};
110    ///
111    /// let conf = Config{
112    ///         // output log info
113    ///         debug: false,
114    ///         debug_log:String::from("logs/grapeTimer.log"),
115    ///         thread_count: 10,
116    ///         // 初始化全局ID的起始ID,可以自行控制
117    ///         // Initialize the starting ID of the global ID, which can be controlled by yourself
118    ///         id_seed: 1,
119    ///         id_type: IDMode::SequenceId
120    ///     };
121    ///
122    /// timer::init_schedule(conf);
123    /// ```
124    pub fn init_schedule(conf:Config) -> TResult<()> {
125        let mut l_config = Inter.config.lock().unwrap();
126        l_config.thread_count = conf.thread_count;
127        l_config.id_seed = conf.id_seed;
128        l_config.debug = conf.debug;
129        l_config.id_type = conf.id_type;
130
131        let config = LogConfigBuilder::builder()
132            .path(conf.debug_log)
133            .size(1 * 100)
134            .roll_count(10)
135            .level("debug")
136            .output_file()
137            .output_console()
138            .build();
139        let r = simple_log::new(config);
140        match r {
141            Err(e) => {
142                return Err(TError::new(TErrorKind::Other(e)));
143            }
144            Ok(v) => {}
145        }
146
147        Inter.thread_pool.lock().unwrap().rebuild(conf.thread_count,conf.debug);
148        set_seed(l_config.id_seed);
149        Ok(())
150    }
151
152    /// create a new ticker action [创建一个计时器任务]
153    ///
154    /// # Examples
155    ///
156    /// ```
157    /// use grapeTimerR::timer;
158    /// use std::time;
159    ///
160    /// fn executor_task(id:u64) {
161    ///     println!("on function mode:{}",chrono::Local::now().to_rfc2822());
162    /// }
163    /// // 使用函数方式执行代码 Use function to execute code
164    ///  timer::spawn_ticker(time::Duration::from_millis(5000),2,executor_task);
165    ///  // 使用闭包模式 Use closure function
166    ///  timer::spawn_ticker(time::Duration::from_millis(5000),2,|x| {
167    ///         println!("on ticker:{}",chrono::Local::now().to_rfc2822());
168    ///     });
169    /// ```
170    pub fn spawn_ticker(tick:time::Duration, loopCount:i32, f: impl Fn(u64) + Send+Sync + 'static) -> TResult<u64> {
171        let task_action =  ClosuresAction::new("", next_uuid(), loopCount, tick, f);
172        let r = Inter.thread_pool.lock();
173        match r {
174            Err(e) => { Err(TError::new(TErrorKind::Other(e.to_string()))) },
175            Ok(mut v) => {
176                let task_id = task_action.id();
177                v.spawn(Arc::new(task_action));
178                Ok(task_id)
179            }
180        }
181    }
182
183    /// create a new trait ticker action [创建一个Trait模式计时器任务]
184    ///
185    /// # Examples
186    ///
187    /// ```
188    /// use grapeTimerR::schedule::schedule::TaskAction;
189    /// use std::sync::Arc;
190    ///
191    ///
192    /// struct ExempleAction {}
193    ///
194    /// // 首先我们定义一个结构体
195    /// //First we define a struct
196    /// impl TaskAction for ExempleAction {
197    ///     // 实际执行的代码段
198    ///     // Code snippet executed
199    ///     fn execute(&self, id: u64) {
200    ///         println!("on trait struct:{}",chrono::Local::now().to_rfc2822());
201    ///     }
202    ///
203    ///     // 不使用的话,返回一个空字符串
204    ///     // If not used, return an empty string,like ""
205    ///     fn date_format(&self) -> &str {
206    ///         return ""
207    ///     }
208    ///
209    ///     // 如果你不使用date_format,就必须使用这个参数,否则异常。
210    ///     // If you don't use date_format, you must use this parameter, otherwise it is panic.
211    ///     // 时间单位 毫秒 ,time unit is millisecond
212    ///     fn tick(&self) -> u64 {
213    ///         return 5000;
214    ///     }
215    ///
216    ///     // 这里需要自定义ID或将其设置为一个组的ID,所以停止任务会停止这个组
217    ///     // Here you need to customize the ID or set it to the GroupId or TaskType Id,
218    ///     // so stopping the task will stop the group
219    ///     fn id(&self) -> u64 {
220    ///         return 18888;
221    ///     }
222    ///
223    ///     // 循环的次数
224    ///     fn loop_count(&self) -> i32 {
225    ///        return 15;
226    ///     }
227    /// }
228    ///    // 使用trait任务,可以简化部分实际逻辑
229    ///    // Using trait tasks can simplify part of the actual logic
230    ///    timer::spawn_trait(Arc::new(ExempleAction{}));
231    /// ```
232    pub fn spawn_trait(ft:Arc<dyn TaskAction>) -> TResult<u64> {
233        let r = Inter.thread_pool.lock();
234        match r {
235            Err(e) => { Err(TError::new(TErrorKind::Other(e.to_string()))) },
236            Ok(mut v) => {
237                let taskId = ft.id();
238                v.spawn(ft);
239                Ok(taskId)
240            }
241        }
242    }
243
244    /// create a new ticker action [创建一个计时器任务]
245    ///
246    /// # Examples
247    ///
248    /// ```
249    /// use grapeTimerR::timer;
250    /// timer::spawn_date("day 19:30:00",1,|id| {
251    ///        println!("on date:{}",chrono::Local::now().to_rfc2822());
252    /// });
253    /// ```
254    pub fn spawn_date(dateformate:&str, loopCount:i32, f: impl Fn(u64) + Send+Sync + 'static) -> TResult<u64> {
255        let task_action =  ClosuresAction::new(dateformate, next_uuid(), loopCount, time::Duration::from_secs(0), f);
256        let r = Inter.thread_pool.lock();
257        match r {
258            Err(e) => { Err(TError::new(TErrorKind::Other(e.to_string()))) },
259            Ok(mut v) => {
260                let task_id = task_action.id();
261                v.spawn(Arc::new(task_action));
262                Ok(task_id)
263            }
264        }
265    }
266
267     /// Used to use asynchronous tasks in Timer [用于在代码中使用异步任务]
268     ///
269     /// # Examples
270     ///
271     /// ```
272     /// use grapeTimerR::timer;
273     /// timer::block_on_rt(async {
274     ///     println!("block on");
275     /// });
276     /// ```
277    pub fn block_on_rt<F>(future: F) -> TResult<()>
278         where
279             F: Future,
280             F::Output: Send + 'static,
281     {
282         let r =Inter.thread_pool.lock();
283         match r {
284             Err(e) => { Err(TError::new(TErrorKind::Other(e.to_string()))) },
285             Ok(mut v) => {
286                 v.block_on(future);
287                 Ok(())
288             }
289         }
290     }
291
292    /// Used to use asynchronous tasks in Timer [用于在代码中使用异步任务]
293    ///
294    /// # Examples
295    ///
296    /// ```
297    /// use grapeTimerR::timer;
298    /// timer::spawn_rt(async {
299    ///     println!("spawn on");
300    /// });
301    /// ```
302    pub fn spawn_rt<F>(future: F) -> TResult<()>
303        where
304            F: Future + Send + 'static,
305            F::Output: Send + 'static,
306    {
307        let r =Inter.thread_pool.lock();
308        match r {
309            Err(e) => { Err(TError::new(TErrorKind::Other(e.to_string()))) },
310            Ok(mut v) => {
311                v.spawn_rt(future);
312                Ok(())
313            }
314        }
315    }
316
317    /// stop a ticker action [停止一个计时器任务]
318    ///
319    /// # Examples
320    ///
321    /// ```
322    /// use grapeTimerR::timer::stop_ticker;
323    /// stop_ticker(123);
324    /// ```
325    pub fn stop_ticker(id:u64) -> TResult<()> {
326        let r = Inter.thread_pool.lock();
327        match r {
328            Err(e) => { Err(TError::new(TErrorKind::Other(e.to_string()))) },
329            Ok(mut v) => {
330                let r = v.stop_task(id)?;
331                Ok(r)
332            }
333        }
334    }
335
336    /// wait main thread forever [永远阻塞主线程,非必须调用]
337    ///
338    pub fn wait_forever() {
339        loop {
340            std::thread::sleep(time::Duration::from_secs(1));
341        }
342    }
343}