Files
orbit/docs/examples/delayed-task.md

60 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 相对延迟与原请求恢复
源码:[delayed-task/main.go](../../sdk/go/examples/delayed-task/main.go)。示例提交等待1500毫秒的对象任务,启动自动Worker,核对实际执行历史,再在任务完成后重报原请求。处理器原样返回示例JSON,无外部副作用。
## 准备与运行
先完成[迁移和Worker凭据初始化](../sdk/worker.md#1-可运行的文本规范化示例),启动当前Orbit。凭据需要任务提交、读取及Worker连接/消费权限,队列须有可用额度。仓库根目录执行:
```sh
cd sdk/go
ORBIT_URL=http://127.0.0.1:8080 \
ORBIT_CREDENTIALS_FILE=../../.local/worker.credentials.json \
go run ./examples/delayed-task
```
也可用ORBIT_TOKEN和ORBIT_QUEUE_ID覆盖凭据文件中的对应值。示例总上下文20秒、任务总时限15秒、单次执行5秒、最多1次尝试;每次运行使用独立操作及处理器身份,不会消费其他处理器的任务。
预期输出:
```text
task=<任务ID> delay_ms=1500
state=SUCCEEDED attempts=1 no_early_start=true original_receipt=true worker_drained=true
```
检查依据是同一个数据库的CreatedAt、AvailableAt及尝试创建/开始时间,不把客户端墙钟或sleep结束当作执行授权。Worker正常排空后退出;任务、结果和审计保留。
## SDK调用
以下为函数中的调用片段,完整imports及错误处理见源码:
```go
request := orbit.SubmitTaskRequest{
QueueID: queueID,
Handler: "object.prepare", HandlerVersion: "v1", PayloadVersion: "v1",
Payload: json.RawMessage(`{"object_ref":"objects/input"}`),
DelayMS: 5000,
TaskTimeoutMS: 60000,
Retry: orbit.RetryPolicy{MaxAttempts: 1, AttemptTimeoutMS: 10000},
}
accepted, err := client.SubmitTask(ctx, operationKey, request)
if err != nil { return err }
fmt.Println(accepted.Task.ID, accepted.Task.AvailableAt)
```
`delay_ms`相对首次成功受理事务中的数据库时间计算,保存为`available_at`。同一幂等键重报仍提交原等待时长;不按当前时间重算available_at,不生成新键。响应是原受理回执,即使任务后来已经成功,回执中仍可能是WAITING;当前状态通过GetTask查询。
指定绝对时刻时使用AvailableAt并令DelayMS为0。非零delay_ms和available_at不能同时提供。等待时长必须小于task_timeout_ms;总时限包含等待时间。start_deadline_at不能早于计算后的available_at。所有时间规则及400/409错误见[任务接口](../api/tasks.md)。
服务端停机、队列暂停、没有兼容Worker或额度不足都可能让开始时间晚于available_at;到期后才可领取,不承诺准点执行。自动失败重试使用retry中的退避策略,不再次应用初始delay_ms。
## 失败与持久化边界
示例网络错误时非零退出,已打印任务ID可用于核对;不在同一次运行中换键重提。真实接入须在第一次请求前保存操作身份和请求,可使用[业务事务Outbox](task-outbox.md)。本例生成的新身份仅用于独立演示,重新运行不是上一次进程的恢复。
Outbox若使用delay_ms,等待从Orbit受理开始计算,不从本地业务事务或Outbox创建时间计算。需要固定业务时刻时冻结available_at;若发送时该时刻已超出接口容差,按拒绝结果核查,不静默改成“从现在起再等”。
旧服务不识别delay_ms。先更新服务端,再让调用方启用该字段;省略/零值保持旧请求摘要。计划模板拒绝非零delay_ms,时间由计划规则定义。人工重试的新开始时间使用其专门接口参数,不继承原任务的初始延迟。
`make integration`执行此例、真实HTTP/Worker延迟用例,以及重试退避期间全节点退出后的恢复测试;结果见[本轮报告](../reports/phase-3-delay-recovery.md)。