1use chrono_tz::Asia::Shanghai;
2
3use puniyu_builder::task::TaskBuilder;
4use puniyu_logger::info;
5use puniyu_logger::owo_colors::OwoColorize;
6use std::sync::Arc;
7use std::time::Instant;
8use tokio::sync::OnceCell;
9pub use tokio_cron_scheduler;
10use tokio_cron_scheduler::{JobBuilder, JobScheduler};
11pub use uuid::Uuid;
12pub static SCHEDULER: OnceCell<Arc<JobScheduler>> = OnceCell::const_new();
13
14pub struct Task {
15 pub plugin_name: &'static str,
17 pub builder: Arc<dyn TaskBuilder>,
19}
20
21impl From<Task> for tokio_cron_scheduler::Job {
22 fn from(task: Task) -> Self {
23 JobBuilder::new()
24 .with_timezone(Shanghai)
25 .with_cron_job_type()
26 .with_schedule(task.builder.cron())
27 .unwrap()
28 .with_run_async(Box::new(move |_uuid, _lock| {
29 let builder = task.builder.clone();
30 Box::pin(async move {
31 let name = builder.name().to_string();
32 let task_run = builder.run();
33 let start_time = Instant::now();
34 let prefix = "task".fg_rgb::<176, 196, 222>();
35 let message = name.fg_rgb::<255, 192, 203>();
36 info!("[{}:{}] 开始执行", prefix, message);
37
38 task_run.await;
39
40 let duration = start_time.elapsed().as_millis();
41 info!("[{}:{}] 执行完成,耗时: {}ms", prefix, message, duration);
42 })
43 }))
44 .build()
45 .unwrap()
46 }
47}
48
49pub async fn init_scheduler() {
50 SCHEDULER
51 .get_or_init(|| async {
52 let sched = JobScheduler::new().await.unwrap();
53 Arc::new(sched)
54 })
55 .await;
56}