ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

simple-starter-schedule

simple-starter-schedule simple-starter-schedulesimple-starter-schedule是 simple-starter 框架的定时任务插件用宏声明任务由插件在启动期装配由框架托管运行与关闭。任务是「注册物 任务体」宏在编译期注册任务描述插件在收尾期解析目标实例并构建任务体任务由框架的后台任务机制启动与收编因此任务体可以安全持有组件实例触发规则可写在宏上作为默认值也可由配置覆盖、按环境关闭需显式注册插件否则任务不会被调度。一、快速开始usestd::sync::Arc;usesimple_starter_core::{Application,component,tracing};usesimple_starter_schedule::{SchedulePlugin,cron_job,scheduled};// 组件方法任务任务体是组件方法其依赖由组件在装配期完成注入#[component]pubstructHeartbeatService{#[inject]repository:ArcRepository,// 任意已注册组件}#[scheduled]implHeartbeatService{#[cron_job(every 30s)]asyncfntick(self){tracing::info!(心跳: {},self.repository.name());}}// 自由函数任务无参 async fn#[cron_job(0 0 3 * * *)]asyncfndaily_cleanup(){tracing::info!(每日清理);}fnmain(){Application::new().register_plugin(SchedulePlugin::new()).run();}二、任务形态形态声明方式签名要求依赖来源组件方法#[scheduled]标注组件impl块块内方法加#[cron_job(...)]async、仅接收self、返回()组件字段注入装配期完成自由函数#[cron_job(...)]标注函数本身无参async fn无需要读配置或组件时开启[app] enable_global_snapshot后经app_config()/app_container()获取怎么选任务体需要依赖注入业务服务、仓库、配置组件时用组件方法形态纯工具性动作清理临时文件、打点上报用自由函数形态即可。签名不合规在编译期报错#[cron_job]method must beasync/ must takeself/ must return()。方法上写了#[cron_job]但所属impl块缺少#[scheduled]时会提示requires #[scheduled] on the enclosing impl block。三、任务名与配置键任务名同时充当配置键与日志标识形态默认任务名示例组件方法类型短名::方法名HeartbeatService::tick自由函数函数名不含模块路径daily_cleanup默认名可能撞名两个模块下的同名自由函数或a::Service::tick与b::Service::tick重名会在启动期报错用显式命名区分#[cron_job(every 30s, name heartbeat)]同一个组件类型可以写多个#[scheduled] impl块各块中带标记的方法都会注册。四、触发规则宏参数给出默认值可留空交给配置写法含义#[cron_job(*/5 * * * * *)]cron 表达式秒级六段秒 分 时 日 月 周#[cron_job(every 30s)]固定间隔整数 s/m/h/d#[cron_job]触发规则全部来自配置cron 表达式按[app] timezone缺省local的时区解释expr与every互斥宏上同时给出即编译报错两者都未给出时必须由配置提供否则启动报错首次触发不在启动瞬间every 30s的任务在启动约 30 秒后首次执行cron 任务对齐到下一个匹配时刻。五、配置任务相关的覆盖与关闭写在[cron]节时区放在[app]与日志时间戳共用配置项类型缺省说明[app] timezone字符串local触发计算与日志时间戳共用local本机时区或HH:MM/-HH:MM[cron] shutdown_grace_ms整数5000关闭时等待在飞任务结束的宽限期毫秒超时强制中止[cron.jobs.任务名]·expr字符串—覆盖宏上的 cron 表达式[cron.jobs.任务名]·every字符串—覆盖宏上的固定间隔[cron.jobs.任务名]·enabled布尔true置false关闭该任务[app] timezone 08:00 [cron] shutdown_grace_ms 5000 # 覆盖宏上的触发规则整体替换便于按环境调整频率 [cron.jobs.HeartbeatService::tick] every 10s # 关闭任务 [cron.jobs.daily_cleanup] enabled false覆盖是整体替换配置给出expr或every之一就完全采用配置的规则不与宏默认值混用只写enabled时触发规则沿用宏默认值。生效优先级由 core 的配置合并顺序保证宏默认值 插件默认配置 用户add_default_configapplication.toml Profile 配置如application-dev.tomlProfile 分层天然生效。启动期校验避免配置静默失效配置里出现未注册的任务名、非法表达式、或某个任务同时给出expr与every都会让应用启动失败并指出具体任务错误信息中会列出已注册任务名。enabled false的任务不构建也不校验其表达式。六、运行语义关注点行为触发推进以上一次目标时刻为基准推进长周期不累积漂移某次执行耗时超过触发周期时直接跳到当前时刻之后不重叠、不补跑并发同一任务串行执行本轮任务体结束后才开始下一轮等待异常隔离每次触发在独立任务中执行单次 panic 只记错误日志含 panic 内容后续周期照常关闭收编停止后续触发 → 为在飞任务体保留宽限期 → 超时强制中止收编完成后才销毁组件因此任务体持有的组件实例不会阻碍销毁调度侧日志日志级别含义Scheduled job registered: [name]INFO任务已构建启动期Scheduled job [name] disabled by configurationINFO被配置关闭未构建No scheduled jobs registered.INFO一个任务都没注册Scheduled job [name] triggeredDEBUG一轮触发开始Scheduled job [name] panicked: …ERROR任务体 panic已隔离Scheduled job [name] stopped: …ERROR触发规则无法继续计算如表达式永不匹配该任务停止Scheduled job [name] exceeded the shutdown grace period; abortingWARN关闭时在飞任务超过宽限期被强制中止All scheduled jobs stopped.INFO所有任务驱动已退出关闭流程调度侧不打印绝对触发时刻或倒计时——日志行的时间戳即事件时刻任务体的业务日志由任务体自行打印。七、约束与排障必须注册插件未注册SchedulePlugin时任务不会被调度启动日志中也不会出现任务清单。组件方法任务要求目标类型已注册为组件#[component]/#[provider]否则启动期报错。避免在工作线程里同步阻塞任务体中的阻塞调用std::thread::sleep、同步 IO、长 CPU 计算会占住运行时工作线程拖慢同线程上的其它任务与定时器配置[runtime] worker_thread_num 1时尤其明显。常见报错报错原因Duplicate scheduled job name: …任务名重复用name ...区分Unknown scheduled job(s) in [cron.jobs]: […]配置里写了不存在的任务名多为拼写错误错误信息会列出已注册任务invalid cron expression …/invalid interval …触发规则不合法declares both expr and every/declares neither expr nor every触发规则给多了或一个都没给宏上冲突表现为编译错误
返回列表