概述
洛玖采用基于 FFI 消息总线的定时任务系统。插件通过向 luo9_task topic 发布请求来注册定时任务,luo9_bot内含轻量级 Cron 调度器,到期后通过同一 topic 向插件推送事件。
架构
1 2 3 4 5 6 7 8
| 插件 ──publish──> luo9_task (请求: schedule/cancel) │ ┌───────┴───────┐ │ Cron 调度器 │ ← luo9_bot内 tokio task │ 每秒检查匹配 │ └───────┬───────┘ │ 插件 <──pop──── luo9_task (事件: tick)
|
Task 协议
注册定时任务
插件发布 JSON 到 luo9_task topic:
1 2 3 4 5 6
| { "action": "schedule", "task_name": "my_task", "cron": "0 */5 * * * *", "payload": "任意数据" }
|
取消定时任务
1 2 3 4
| { "action": "cancel", "task_name": "my_task" }
|
接收定时事件
调度器触发后,插件通过订阅 luo9_task 接收:
1 2 3 4 5
| { "event": "tick", "task_name": "my_task", "payload": "任意数据" }
|
区分方式:请求有 action 字段,事件有 event 字段。
Cron 表达式
6 字段格式:秒 分 时 日 月 周
| 字段 |
范围 |
| 秒 |
0-59 |
| 分 |
0-59 |
| 时 |
0-23 |
| 日 |
1-31 |
| 月 |
1-12 (支持 JAN-DEC) |
| 周 |
0-7 (0和7=周日, 支持 SUN-SAT) |
特殊字符
| 字符 |
说明 |
示例 |
* |
所有值 |
* * * * * * |
? |
不指定(日/周互斥) |
0 0 12 15 * ? |
- |
范围 |
0 0 9-17 * * * |
, |
列表 |
0 0 0 1,15 * * |
/ |
步长 |
0 */5 * * * * |
L |
最后(日: 月末; 周: 最后周X) |
0 0 0 L * * / 0 0 0 * * 5L |
W |
最近工作日(不跨月) |
0 0 0 15W * * |
# |
第N个星期X |
0 0 0 * * 2#3(第3个周一) |
常用示例
| Cron 表达式 |
含义 |
0 */5 * * * * |
每5分钟 |
0 0 9 * * * |
每天 9:00 |
0 0 0 * * 1 |
每周一 0:00 |
0 0 12 15 * ? |
每月15号 12:00 |
0 0 0 L * * |
每月最后一天 0:00 |
0 0 0 * * 5L |
每月最后一个周五 0:00 |
0 0 0 * * 2#3 |
每月第3个周一 0:00 |
插件端使用(Rust)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| use luo9_sdk::bus::Bus;
fn register_task() { let request = serde_json::json!({ "action": "schedule", "task_name": "epic_remind", "cron": "0 0 9 * * *", "payload": "epic_daily_check" }); Bus::topic("luo9_task").publish(&request.to_string()).ok(); }
fn cancel_task() { let request = serde_json::json!({ "action": "cancel", "task_name": "epic_remind" }); Bus::topic("luo9_task").publish(&request.to_string()).ok(); }
|