grapeTimerR/lib.rs
1/*!
2[](https://www.rust-lang.org/)
3[](https://github.com/ellerbrock/open-source-badges/)
4[](https://crates.io/crates/grapeTimerR)
5[](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}