From 3579475c9be1855e933fa61e5c02d245d91fb018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E8=BF=90=E5=AE=B6?= Date: Mon, 28 Oct 2024 20:22:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8inventory=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E8=87=AA=E5=8A=A8=E5=A4=84?= =?UTF-8?q?=E7=90=86=EF=BC=8C=E6=97=A0=E9=9C=80=E6=89=8B=E5=8A=A8=E7=BC=96?= =?UTF-8?q?=E5=86=99=E4=BB=A3=E7=A0=81=E6=B3=A8=E5=86=8C=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 7 +++++++ Cargo.toml | 3 ++- library/Cargo.toml | 1 + library/src/task.rs | 30 ++++++++++++++++++++++++++++-- macro/src/task.rs | 17 ++++++++++++----- server/src/lib.rs | 3 +-- server/src/tasks/mod.rs | 10 +--------- 7 files changed, 52 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70b022e..f0564d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1093,6 +1093,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inventory" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" + [[package]] name = "ipnet" version = "2.9.0" @@ -1179,6 +1185,7 @@ dependencies = [ "http-body-util", "hyper", "i18n", + "inventory", "jsonwebtoken", "lazy_static", "macro", diff --git a/Cargo.toml b/Cargo.toml index 33f2aad..577200b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,4 +60,5 @@ strum_macros = "0.26.3" hex = "0.4.3" redis = "0.27.4" deadpool-redis = "0.18.0" -chrono-tz = "0.10.0" \ No newline at end of file +chrono-tz = "0.10.0" +inventory = "0.3.15" \ No newline at end of file diff --git a/library/Cargo.toml b/library/Cargo.toml index 2337d57..c558c61 100644 --- a/library/Cargo.toml +++ b/library/Cargo.toml @@ -39,6 +39,7 @@ hex = { workspace = true } redis = { workspace = true, features = ["tokio-comp", "json"] } deadpool-redis = { workspace = true } chrono-tz = { workspace = true } +inventory = { workspace = true } domain = { path = "../domain" } i18n = { path = "../i18n" } diff --git a/library/src/task.rs b/library/src/task.rs index ca3a7a9..23e4b4b 100644 --- a/library/src/task.rs +++ b/library/src/task.rs @@ -3,8 +3,14 @@ use std::{future::Future, pin::Pin, sync::Arc, time::Duration}; use chrono_tz::Tz; use tokio_cron_scheduler::{Job, JobScheduler, JobSchedulerError}; +pub use inventory::submit; + type TaskFun = dyn Fn() -> Pin + Send>> + Send + Sync; +pub trait TaskMethod: Send + Sync + 'static { + fn ge_task(&self) -> Task; +} + pub struct Task{ pub job: Arc, pub cron: Option, @@ -13,14 +19,15 @@ pub struct Task{ } /// 启动定时任务 -pub async fn start(tasks: Vec) { +pub async fn start() { + let tasks = get_task_methods(); match schedule(tasks).await { Ok(_) => tracing::info!("定时任务启动成功"), Err(err) => tracing::error!(error = ?err, "定时任务启动失败"), } } -async fn schedule(tasks: Vec) -> Result<(), JobSchedulerError> { +async fn schedule(tasks: Vec>) -> Result<(), JobSchedulerError> { let mut scheduler = JobScheduler::new().await?; scheduler.init().await?; @@ -61,3 +68,22 @@ async fn schedule(tasks: Vec) -> Result<(), JobSchedulerError> { scheduler.start().await?; Ok(()) } + +inventory::collect!(&'static dyn TaskMethod); + +#[macro_export] +macro_rules! submit_task { + ($ty:ident) => { + ::library::task::submit! { + &$ty as &dyn ::library::task::TaskMethod + } + }; +} + +fn get_task_methods() -> Vec> { + let mut result = Vec::>::new(); + for method in inventory::iter::<&dyn TaskMethod> { + result.push(Arc::new(method.ge_task())); + } + result +} diff --git a/macro/src/task.rs b/macro/src/task.rs index 9fbb32f..8b8633e 100644 --- a/macro/src/task.rs +++ b/macro/src/task.rs @@ -77,12 +77,12 @@ pub fn gen_task(attr: TokenStream, item: TokenStream) -> TokenStream { let TaskArgs{ cron, interval, time_zone } = parse_macro_input!(attr as TaskArgs); // 将 method 转换为小写并生成标识符 - let vis = func.vis.clone(); + // let vis = func.vis.clone(); let ident = func.sig.ident.clone(); let result = quote!{ let mut _result = library::task::Task { - job: std::sync::Arc::new(|| Box::pin(#ident ())), + job: std::sync::Arc::new(|| Box::pin(#ident::#ident ())), cron: None, interval: None, time_zone: None, @@ -100,11 +100,18 @@ pub fn gen_task(attr: TokenStream, item: TokenStream) -> TokenStream { }; let generated = quote! { - #vis fn #ident () -> library::task::Task { + #[allow(non_camel_case_types)] + struct #ident; + impl #ident { #func - - #result } + impl library::task::TaskMethod for #ident { + fn ge_task(&self) -> library::task::Task { + #result + } + } + + ::library::submit_task!(#ident); }; TokenStream::from(generated) diff --git a/server/src/lib.rs b/server/src/lib.rs index 5d58218..2600a88 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -1,6 +1,5 @@ use axum::{body::Body, extract::Request, http, routing::get, Router}; use library::{config, task}; -use tasks::get_tasks; use tower::ServiceBuilder; use tower_http::trace::TraceLayer; @@ -15,7 +14,7 @@ pub async fn serve() { tracing::info!("服务监听地址: {}", addr); // 启动任务 - task::start(get_tasks()).await; + task::start().await; // 启动应用服务 axum::serve(listener, init()).await.unwrap(); } diff --git a/server/src/tasks/mod.rs b/server/src/tasks/mod.rs index 49a9f42..544d4ae 100644 --- a/server/src/tasks/mod.rs +++ b/server/src/tasks/mod.rs @@ -1,9 +1 @@ -use library::task::Task; - -pub mod google_tasks; - -/// 定时任务维护器 -pub fn get_tasks() -> Vec { - vec![google_tasks::xxx_task(), google_tasks::xxx_task2()] -} - +pub mod google_tasks; \ No newline at end of file