mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-30 22:26:38 +08:00
5.4 KiB
5.4 KiB
name, description
| name | description |
|---|---|
| new-async-task | Wavelet 项目专用:新增或修改 Asynq 异步任务、后台任务、定时任务、任务元数据、TaskHandler、TaskParam、PayloadValidator、AppendLog、任务重试、任务执行记录或 Admin 任务 API 时必须使用。 |
异步任务开发
开始前阅读根目录 AGENTS.md。只修改任务相关链路,遵守项目路由、日志、数据库迁移和质量门禁要求。
开始前
按任务范围检查当前实现:
internal/task/handler.go:TaskHandler、TaskResult、PayloadValidatorinternal/task/meta.go:TaskMeta、TaskParaminternal/task/executor.go:下发、执行、日志、重试、OnTaskCompleted订阅internal/task/handlers/register.go:Handler 和元数据注册(由 bootstrap 调用)internal/bootstrap/bootstrap.go:任务注册与进程级装配入口internal/task/worker/worker.go:Worker 路由和队列internal/task/scheduler/scheduler.go:定时调度internal/apps/admin/task/routers.go:Admin 任务 APIinternal/model/task_execution.go:执行记录和日志持久化
需要模板时阅读 references/CODE-EXAMPLES.md。
实现要求
任务定义
- 在
internal/apps/<module>/tasks.go定义任务类型、Admin 任务类型和TaskMeta。 - Asynq 任务类型使用
<module>:<action>格式。 - 完整设置
Type、AsynqTask、Name、Description、MaxRetry、Queue、Retryable。 - 有参数任务必须定义 payload struct。
TaskParam.Name必须与 payload JSON tag 一致。TaskParam只描述前端表单,不代替服务端校验。
Handler
- Handler 必须实现
task.TaskHandler。 - 有参数任务必须实现
task.PayloadValidator,负责校验和标准化 Admin 下发参数。 Execute必须再次解析 payload;不要假设入口一定经过 Admin 校验。- 成功返回
&task.TaskResult{Message: ..., Detail: ...}。 - 失败返回 error,由任务框架处理状态和重试。
- 不要吞掉关键错误。
- 复杂 SQL 放到
internal/model/或模块内的业务服务层(如internal/apps/<module>/service.go或logics.go)。
注册
- 在
internal/task/handlers/register.go同时注册 Handler 和TaskMeta。 - 不要在其他位置单独注册任务。
- 禁止在业务包
routers.go或init()中调用task.RegisterHandler;统一由bootstrap.RegisterTasks()→taskhandlers.Register()在进程启动时装配。 - 任务完成钩子(如 push 通知)通过
task.OnTaskCompleted注册,在bootstrap.RegisterTaskListeners()中装配(Worker/all进程)。
进程装配分工
| 进程 | 注册入口 |
|---|---|
api |
cmd/api.go → bootstrap.RegisterAPI()(含 RegisterTasks) |
worker |
worker.StartWorker() → bootstrap.RegisterWorker()(含 RegisterTasks + RegisterTaskListeners) |
scheduler |
scheduler.StartScheduler() → bootstrap.RegisterScheduler() |
all |
cmd/all.go → bootstrap.RegisterAll() |
所有 Register* 使用 sync.Once,重复调用安全。
测试
- 依赖已注册任务类型或 Handler 的测试(如
internal/apps/admin/task/routers_test.go),必须在 setup 中显式调用bootstrap.RegisterTasks()。 - 不得依赖
init()副作用或 import 链触发注册。
日志要求
- 在
TaskHandler.Execute中使用task.AppendLog(ctx, format, args...)。 - 记录任务开始、参数摘要、批次进度、关键状态、可继续错误和完成摘要。
- 批量处理按批次记录;禁止为大循环中的每条数据写日志。
- 不要直接修改任务日志的 Redis key 或
w_task_executions.log。
日志框架约束:
- 执行状态实时写入数据库:
pending、running、succeeded、failed。 - 实时日志写入 Redis,每个任务最多保留最近 1000 行。
- Redis 日志 TTL 为 24 小时,每次追加时刷新。
- 查询时优先返回 Redis 日志,Redis 不存在时读取数据库。
- 任务成功或自动重试耗尽后,将日志写入数据库并删除 Redis 缓冲。
- 自动重试期间保留同一 taskID 的 Redis 日志。
重试要求
- Handler 返回 error 以触发 Asynq 自动重试。
- 不要在 Handler 内自行实现重复重试循环。
- Admin 手动重试只允许:
- 原任务状态为
failed Retryable=trueRetryCount < MaxRetry
- 原任务状态为
- 修改重试行为时同时检查:
internal/task/executor.gointernal/model/task_execution.gointernal/apps/admin/task/routers.go- 前端任务执行列表
定时任务
- 默认定时任务必须通过 Goose SQL 迁移写入
schedules。 - PostgreSQL 和 SQLite 迁移必须同时提供。
- 初始化 SQL 必须幂等。
- 涉及迁移时使用
database-migrationskill。
Admin API
- Handler 放在现有 Admin task 模块或
internal/apps/admin/<module>/。 - 路由只在
internal/router/router.go注册。 - 响应保持
{ "error_msg": "", "data": ... }。 - 分页数据保持
{ "total": 0, "results": [] }。 - Swagger 注释必须完整;API 变化后运行
make swagger。
前端
- 仅任务元数据变化时,优先复用现有动态任务表单,不新增页面。
- API 调用必须通过
frontend/lib/services/。 - 修改 shadcn/ui 时使用
shadcnskill。 - 不使用
any。 - 页面根容器使用
w-full,不添加页面级max-w-*。