use once_cell::sync::OnceCell; use tauri::AppHandle; use tokio_cron_scheduler::{Job, JobScheduler}; use tracing::info; /// 全局调度器实例 /// 使用 OnceCell 确保只创建一次,并在应用生命周期内保持活动 static SCHEDULER: OnceCell = OnceCell::new(); /// 启动每日凌晨1点定时重启任务 /// /// 注意:此函数会启动一个后台任务,调度器会在后台持续运行 /// 调度器的生命周期与应用程序相同 pub async fn start_scheduled_restart_task(app_handle: AppHandle) -> Result<(), Box> { // 如果调度器已经存在,直接返回 if SCHEDULER.get().is_some() { info!("定时重启任务已经启动,跳过重复初始化"); return Ok(()); } // 创建调度器 let scheduler = JobScheduler::new().await?; // 创建每天凌晨1点执行的定时任务 // cron表达式: "0 0 1 * * *" 表示每天1点0分0秒执行 // 格式: sec min hour day_of_month month day_of_week let job = Job::new_async("0 0 1 * * *", move |_uuid, _l| { let app_handle_clone = app_handle.clone(); Box::pin(async move { info!("定时重启任务已触发,正在重启应用程序..."); // 重启应用 app_handle_clone.restart(); // 注意:由于重启操作会终止程序,下面的代码不会执行 }) })?; // 添加任务到调度器 scheduler.add(job).await?; // 启动调度器 scheduler.start().await?; // 将调度器保存到全局静态变量中,确保其不会被清理 SCHEDULER.set(scheduler).map_err(|_| "定时任务调度器已初始化")?; info!("定时重启任务已启动 - 应用程序将在每天凌晨1点重启"); Ok(()) }