Files
orbit/docs/examples/recovery.md

81 lines
4.1 KiB
Markdown
Raw Permalink 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.
# 未知结果的核查与人工重试示例
完整源码:[SDK recovery/main.go](../../sdk/go/examples/recovery/main.go)。只处理本地模拟对象,不调用任何真实外部业务系统。接口细节见[人工恢复手册](../api/task-recovery.md)。
## 准备与运行
从仓库根目录执行,ORBIT_MYSQL_DSN通过环境指向专用开发库;已有基础服务时使用当前迁移及二进制。初始化创建独立演示应用,输出文件必须不存在:
```sh
go run ./cmd/orbit-migrate up
mkdir -p .local
chmod 700 .local
go run ./cmd/orbit-admin bootstrap \
--application recovery-demo --namespace default --environment development \
--queue recovery --worker-access --recovery-access \
--output .local/recovery.credentials.json
go run ./cmd/orbit
```
另开终端,从仓库根目录执行:
```sh
cd sdk/go
ORBIT_URL=http://127.0.0.1:8080 \
ORBIT_CREDENTIALS_FILE=../../.local/recovery.credentials.json \
go run ./examples/recovery
```
演示凭据为了完整运行同时包含Worker与人工管理权限;生产将它们分开。凭据文件0600、token不输出;也接受ORBIT_TOKEN/ORBIT_QUEUE_ID,环境值优先。
## 实际调用链
1. 用独立处理器名提交一个对象引用,领取/开始后报告UNKNOWN,任务进入NEEDS_REVIEW。
2. 模拟人工核实全部旧执行结束且操作未完成,带证据引用和版本ReviewTask,核查为FAILED。
3. 原键重报核查,确认同audit_id和deduplicated=true。
4. RetryTask声明可安全重新执行并指定新总预算60秒,取得retry_of指向原任务的新任务。
5. Worker开始新任务、报告SUCCEEDED;查询原任务仍FAILED、新任务SUCCEEDED。
6. 查询原任务操作列表及重试审计详情,通过GetTaskSource核对新任务的直接原任务,排空并关闭Worker连接。
预期输出,标识由实际执行生成:
```text
source_kind=MANUAL_RETRY parent=<原任务ID>
source=<原任务ID> state=FAILED retry=<新任务ID> state=SUCCEEDED audit=<审计ID> operations=4
```
操作数包含本例受理、原结果、核查和人工重试;以本次实际查询为准。示例不删除任务、审计或尝试。重复运行创建独立演示任务,每次保留原历史。
[来源接口](../api/task-source.md)仅返回直接父任务,重复人工重试沿后继继续,不递归加载整条链;查询不产生新的审计或改写历史。
## 接入片段
下方在已有客户端和已核实的current任务上下文中调用;完整imports/main及错误处理见源码。
```go
review, err := client.ReviewTask(ctx, current.ID, reviewKey, orbit.ReviewTaskRequest{
ExpectedRevision: current.Revision,
Reason: "已核实全部旧执行结束,操作未完成",
EvidenceRef: "evidence:reconciliation-001",
ExecutionSettled: true,
Outcome: orbit.TaskFailed,
Result: json.RawMessage(`{"confirmed":true}`),
})
if err != nil { return err }
retry, err := client.RetryTask(ctx, current.ID, retryKey, orbit.RetryTaskRequest{
ExpectedRevision: review.Task.Revision,
Reason: "同一业务操作可以安全重新执行",
EvidenceRef: "evidence:safe-retry-001",
SafeToRetry: true,
TaskTimeoutMS: 60000,
})
if err != nil { return err }
fmt.Println(retry.Task.ID, *retry.Task.RetryOf, retry.AuditID)
```
生产先持久化每次操作的key与完整请求,再发HTTP;响应丢失必须用原键、原版本、原结论重报。不能将同键回执中的新revision塞回原请求,不能看到UNKNOWN就直接RetryTask,也不能让审核按钮默认勾选“旧执行已结束”。
本程序为了清楚展示调用而使用单连接协议SDK及20秒总运行上限;错误非零退出,不包含持久化管理操作Outbox。失败后的任务须查询状态/历史再处理,60秒时限不意味着不确定效果会自动变成失败。持续Worker运行使用[自动Worker SDK](../sdk/worker-runtime.md)。
`make integration` 在隔离MySQL中运行本例及真实HTTP故障:核查和重试都在服务端提交后丢失响应,再原身份核对同一审计和子任务;旧Worker迟到成功只进入证据。外部证据的真实性与物理停止仍由管理流程核实。