feat: add reusable MySQL outbox and HTTP lifecycle example
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
这份手册把 SDK、HTTP 查询和 WebSocket 结果通知串成一条可落地的接入链路。它只描述平台协议,不包含任何业务系统名称、行业规则或外部副作用。
|
||||
|
||||
完整可运行的业务宿主见[HTTP 服务示例](../examples/http-service.md),可复用事务能力见[MySQL Outbox 包](outbox-mysql.md)。
|
||||
|
||||
## 1. 接入边界
|
||||
|
||||
业务服务保存操作身份和请求正文,再调用 SDK 提交。`Idempotency-Key` 必须由业务库或 Outbox 持久化,网络超时、进程重启和响应不明时复用原键;不能生成新键猜测服务端是否已提交。受理回执只表示平台已经保存请求,不能当作任务或流程完成。
|
||||
@@ -24,19 +26,19 @@ taskID := receipt.Task.ID
|
||||
|
||||
## 2. 完成通知与权威查询
|
||||
|
||||
结果通知使用 Event WebSocket。连接时声明 `orbit.events.v1` 子协议和允许的来源,SDK 自动发送心跳、在连接断开后重连,并把上一次未确认的投递证明带回新连接。处理器完成业务事务后再调用 `Ack`;处理器失败或进程在提交前退出时不要确认,平台会在租约到期后重投同一交付。
|
||||
结果通知使用 Event WebSocket。连接时声明 `orbit.events.v1` 子协议和允许的来源,SDK 自动发送心跳、在连接断开后重连,并把上一次未确认的投递证明带回新连接。自动消费器的处理器完成业务事务后返回 nil,SDK 再发送 ACK;处理器失败或进程在提交前退出时不要确认,平台会在租约到期后重投同一交付。
|
||||
|
||||
```go
|
||||
consumer := orbit.NewEventConsumer(api, orbit.EventConsumerOptions{
|
||||
consumer, err := 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)
|
||||
Capacity: 8,
|
||||
Handle: func(ctx context.Context, event orbit.ResultEvent) error {
|
||||
// 先按 event.ID 持久化去重,去重与业务更新在同一事务确认后返回 nil。
|
||||
return applyOnce(ctx, event)
|
||||
},
|
||||
})
|
||||
if err != nil { return err }
|
||||
if err := consumer.Run(ctx); err != nil { return err }
|
||||
```
|
||||
|
||||
通知只推动业务侧再次读取权威状态。收到 `task.completed`、`workflow.stopped` 或 `workflow.review_required` 后,调用 `GetTask`、`GetWorkflow` 或对应历史接口;事件快照不替代当前状态,也不表示外部效果已经完成。没有 WebSocket 时可以使用有界 HTTP 查询作为兜底,但必须使用退避、截止时间和业务键,不得无限轮询。
|
||||
|
||||
Reference in New Issue
Block a user