Files
orbit/docs/sdk/production-integration.md

76 lines
5.1 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.
# 生产接入闭环
这份手册把 SDK、HTTP 查询和 WebSocket 结果通知串成一条可落地的接入链路。它只描述平台协议,不包含任何业务系统名称、行业规则或外部副作用。
## 1. 接入边界
业务服务保存操作身份和请求正文,再调用 SDK 提交。`Idempotency-Key` 必须由业务库或 Outbox 持久化,网络超时、进程重启和响应不明时复用原键;不能生成新键猜测服务端是否已提交。受理回执只表示平台已经保存请求,不能当作任务或流程完成。
```go
api, err := orbit.NewClient(baseURL, orbit.Options{Token: token})
if err != nil { return err }
// operationKey 与请求正文一起写入业务库;重试始终复用它。
receipt, err := api.SubmitTask(ctx, operationKey, orbit.SubmitTaskRequest{
QueueID: queueID, Handler: "file.convert", HandlerVersion: "v1",
PayloadVersion: "v1", Payload: json.RawMessage(`{"source_ref":"objects/input.csv"}`),
RecoverySafety: orbit.RecoveryReconcileOnly,
})
if err != nil { return err }
taskID := receipt.Task.ID
```
凭据只授予调用方所需的命名空间、队列和动作范围。生产使用 HTTPS;SDK 不负责 TLS 终止、密钥托管或外部业务核查。所有 API 错误都保留 `RequestID`、稳定错误码和 HTTP 状态,日志不得写入 Token、完整业务键或结果正文。
## 2. 完成通知与权威查询
结果通知使用 Event WebSocket。连接时声明 `orbit.events.v1` 子协议和允许的来源,SDK 自动发送心跳、在连接断开后重连,并把上一次未确认的投递证明带回新连接。处理器完成业务事务后再调用 `Ack`;处理器失败或进程在提交前退出时不要确认,平台会在租约到期后重投同一交付。
```go
consumer := orbit.NewEventConsumer(api, orbit.EventConsumerOptions{
SubscriptionID: subscriptionID,
MaxHandlers: 8,
})
err := consumer.Run(ctx, func(ctx context.Context, delivery orbit.EventDelivery) error {
// 先在业务 Inbox 中按 delivery.EventID 去重,再提交业务事务。
// 返回 nil 后 SDK 才发送 ACK;返回错误会保留交付等待重投。
return applyOnce(ctx, delivery)
})
if err != nil { return err }
```
通知只推动业务侧再次读取权威状态。收到 `task.completed`、`workflow.stopped` 或 `workflow.review_required` 后,调用 `GetTask`、`GetWorkflow` 或对应历史接口;事件快照不替代当前状态,也不表示外部效果已经完成。没有 WebSocket 时可以使用有界 HTTP 查询作为兜底,但必须使用退避、截止时间和业务键,不得无限轮询。
## 3. 流程实例的恢复顺序
流程进入 `NEEDS_REVIEW` 后,接入方按下面顺序处理:
1. 读取当前实例、当前步骤、相关任务和外部证据,保存当时的 `revision`、步骤 `revision` 与 `activation_id`。
2. 使用对应恢复方法提交一个有证据的决定:任务核查、步骤结论、步骤重试、PENDING 接续或等待重建。
3. 等待内部结果被消费,再重新读取实例和步骤;不要把恢复回执快照当作实时状态。
4. 所有核查事项完成后提交 `ContinueWorkflow`,如果实例仍暂停,再单独提交 `Resume`。
5. 使用恢复回执的 `audit_id` 查询操作审计,记录操作者、原因、证据引用和前后状态。
`STATE_CONFLICT`、`UNAVAILABLE` 或响应未知时保留原请求体和原幂等键,先用相同身份核对;不要把版本刷新后重放成另一种决定。服务端会检查流程版本、步骤版本、激活代次、任务归属、未确认结果、预算和截止时间。
## 4. 错误处理约定
| 情况 | 接入方动作 |
| --- | --- |
| HTTP 超时、连接断开、响应未知 | 保留原键和原请求,查询或用原键重报;不生成新键 |
| `STATE_CONFLICT` | 重新读取当前事实和审计,确认是否已有新结果;不能盲目覆盖 |
| `UNAVAILABLE` / readiness 503 | 保留业务 Outbox,等待服务恢复;不能把故障改写为任务失败 |
| `QUEUE_FULL` / `APPLICATION_FULL` | 按业务退避或转人工,保留原身份;释放前不要无限加并发 |
| `NEEDS_REVIEW` | 进入证据核查流程;禁止自动重试未知外部效果 |
| WebSocket 断线 | 不确认未完成处理;让租约自然重投,并使用交付证明去重 |
SDK 的 `revision`、`sequence` 和游标使用字符串 JSON 编码或 `uint64`,业务侧不得转成浮点数。结果正文使用 `json.RawMessage` 保留精确数字;大正文传对象引用并在业务侧设置独立保留和访问策略。
## 5. 上线前清单
- 固定服务端版本和 `git.yuntuo.hk/k2safe/orbit/sdk/go` 的 SDK 版本,执行 `go mod verify`。
- 运行 `make protocol-check`、`make sdk-check` 和对应版本的真实 MySQL 集成回归。
- 持久化提交键、恢复键、业务 Outbox 和消费 Inbox;演练提交回执丢失、进程强杀和 WebSocket 重连。
- 为 `/health/live`、`/health/ready` 和独立 `/metrics` 配置内部监控;确认告警不会自动改写业务状态。
- 验证凭据轮换、权限撤销、备份恢复、MySQL 切换和容量阈值,再进入生产审批。