概述

洛玖采用基于 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();
}