Files
orbit/docs/sdk/README.md

193 lines
12 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.
# Go SDK 接入说明
已实现健康查询、任务单项与[批量提交](../api/batch-tasks.md)/查询/分页/待执行取消、队列创建/查询、[自动 Worker](worker-runtime.md)、[Worker 底层协议 SDK](worker.md) 和 [执行历史查询](../api/execution-history.md)。[安全重试](../api/retries.md) 已提供有限策略、WorkerFailure.Retryable、历史查询及完整例子。[计划调度](../api/schedules.md) 已支持创建、查询、版本发布、暂停/恢复、触发历史与完整示例。[订阅管理](../api/subscriptions.md) 已支持创建、查询、暂停恢复、交付历史与人工重试;[事件消费 SDK](event-consumer.md) 已支持连接、自动心跳、重连与确认。流程构建等后续接口按 [开发计划](../08-development-plan.md) 继续实现。
module:`git.yuntuo.hk/k2safe/orbit/sdk/go`。SDK 使用独立 go.mod,依赖 Go 标准库与 `github.com/coder/websocket v1.8.15`,不引用服务端模型或数据库实现。
## 1. 从初始化到运行示例
需要 Go 1.27.1、MySQL 8.4+。在仓库根目录,通过环境设置专用 ORBIT_MYSQL_DSN:
```sh
go run ./cmd/orbit-migrate up
mkdir -p .local
chmod 700 .local
go run ./cmd/orbit-admin bootstrap \
--application sample-app --namespace default --environment development \
--queue files --output .local/development.credentials.json
go run ./cmd/orbit
```
另开终端,从仓库根目录执行:
```sh
cd sdk/go
ORBIT_URL=http://127.0.0.1:8080 go run ./examples/health
ORBIT_URL=http://127.0.0.1:8080 \
ORBIT_CREDENTIALS_FILE=../../.local/development.credentials.json \
go run ./examples/tasks
```
预期输出,task 为每次运行生成的实际 ID:
```text
liveness=alive readiness=ready scope=database_and_schema
task=<32位任务ID> duplicate=true listed=1 final_state=CANCELLED revision=2
```
重复运行示例会新建一个独立任务并取消它,listed 数量可能增加,最多显示当前页 10 条。数据和审计保留,不执行硬删除。示例只演示受理闭环,尚不执行文件转换。
- [健康示例源码](../../sdk/go/examples/health/main.go):只读,无业务资源写入。
- [任务示例源码](../../sdk/go/examples/tasks/main.go):提交两次同一身份、获取当前状态、列表、带版本取消。
- 任务示例也接受 ORBIT_TOKEN 和 ORBIT_QUEUE_ID,环境值优先于凭据文件。
- 示例发生错误会打印错误并非零退出;打印内容不包含原始 token。
- 初始凭据 30 天有效。初始化行为和错误核对方式见 [凭据文档](../api/authentication.md)。
- `make integration` 会在一次性数据库中自动完成上面的真实服务与 SDK 示例验证。
## 2. 创建客户端与提交任务
下方是接入函数内的调用片段;完整 imports/main 见示例源码。
```go
client, err := orbit.NewClient(baseURL, orbit.Options{Token: token})
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// 应先把 key 与请求内容保存在业务数据库;网络重报必须复用。
key := "file-conversion-operation-001"
request := orbit.SubmitTaskRequest{
QueueID: queueID,
Handler: "file.convert",
HandlerVersion: "v1",
PayloadVersion: "v1",
Payload: json.RawMessage(`{"source_ref":"objects/input.txt","format":"pdf"}`),
RecoverySafety: orbit.RecoveryReconcileOnly,
}
accepted, err := client.SubmitTask(ctx, key, request)
if err != nil {
return err
}
current, err := client.GetTask(ctx, accepted.Task.ID)
if err != nil {
return err
}
fmt.Println(current.ID, current.State, current.Revision)
```
受理回执不是业务执行结果。同键重报返回原始快照;当前状态应使用 GetTask。业务侧创建操作与平台提交之间存在双写边界,接入方应在自身事务中保存操作记录/Outbox,再使用稳定身份提交,不能依靠随机新键补发来“修复”未知结果。
## 3. 取消与错误处理
```go
cancelled, err := client.CancelTask(ctx, current.ID, key+"-cancel", orbit.CancelTaskRequest{
ExpectedRevision: current.Revision,
Reason: "source object was replaced",
})
if err != nil {
var apiErr *orbit.APIError
if errors.As(err, &apiErr) {
// apiErr.Code、StatusCode、RequestID 可用于分支与排查。
// STATE_CONFLICT:先查询;UNAVAILABLE:保留原键和原请求核对。
}
return err
}
fmt.Println(cancelled.Task.State)
```
取消重报必须保留第一次取消时的 expected_revision,不能将响应中的新版本塞回同一幂等请求。已支持独立任务和计划任务的等待、预占、运行和核查状态;运行中受理返回 202,任务状态仍为 RUNNING,需另行查询最终状态。完整语义和运行示例见 [取消契约](../api/cancellation.md)。若此前存在未知效果,本次确认取消不能清除它。
业务错误返回 *orbit.APIError,支持 errors.As 转为 *orbit.HTTPError 查看状态。健康错误或无法识别的网关错误使用 *orbit.HTTPError,不带未知响应正文。网络/上下文错误按标准库错误返回;超时并不能证明服务端没有提交。
## 4. 方法与限制
| 方法 | 请求 / 返回 | 文档 |
| --- | --- | --- |
| SubmitTasks | SubmitTasksRequest / SubmitTasksResult,32项独立幂等与结果 | [批量受理](../api/batch-tasks.md) / [运行场景](../examples/batch.md) |
| CreateSubscription / GetSubscription / ListSubscriptions | 订阅受理、当前配置与队列分页 | [订阅](../api/subscriptions.md) |
| ConfigureSubscription | 显式暂停/继续与版本、原因 | [订阅](../api/subscriptions.md) |
| ListEventDeliveries / GetEventDelivery / RetryEventDelivery | 交付历史、冻结结果和耗尽后追加预算 | [订阅](../api/subscriptions.md) |
| DialEvents / Next / Ack / Ping | 单连接交付、确认与心跳,可用原证明跨连接重报 | [消费 SDK](event-consumer.md) |
| NewEventConsumer / Run / Events / Stats | 自动心跳、重连、受控处理器并发及有界收尾 | [消费 SDK](event-consumer.md) |
| CreateSchedule / GetSchedule / ListSchedules | 计划受理、详情与队列分页 | [计划](../api/schedules.md) |
| PublishSchedule / GetScheduleVersion | 不可变发布与历史版本 | [计划](../api/schedules.md) |
| PauseSchedule / ResumeSchedule / ListScheduleOccurrences | 控制与触发记录 | [计划](../api/schedules.md) |
| Liveness / Readiness | Health | [健康](../api/health.md) |
| SubmitTask | SubmitTaskRequest / SubmitTaskResult | [任务](../api/tasks.md) |
| GetTask | taskID / Task | [任务](../api/tasks.md) |
| ListTasks | ListTasksRequest / TaskPage | [任务](../api/tasks.md) |
| CancelTask | taskID、key、CancelTaskRequest / CancelTaskResult | [任务](../api/tasks.md) |
| CreateQueue | key、CreateQueueRequest / CreateQueueResult | [队列](../api/queues.md) |
| GetQueue | queueID / Queue | [队列](../api/queues.md) |
| ListTaskAttempts | taskID、HistoryPageRequest / AttemptPage | [执行历史](../api/execution-history.md) |
| GetTaskAttempt | taskID、attemptID / Attempt | [执行历史](../api/execution-history.md) |
| ListAttemptEvidence | taskID、attemptID、HistoryPageRequest / AttemptEvidencePage | [执行历史](../api/execution-history.md) |
| GetAttemptEvidence | taskID、attemptID、evidenceID / AttemptEvidence | [执行历史](../api/execution-history.md) |
所有方法第一个参数为 context.Context,返回值之外都返回 error。计划方法的具体参数见对应手册。命令方法要求调用方提供稳定 key,不自动生成或重试。ListTasksRequest 接受 QueueID、State、Limit、Cursor。
Options.HTTPClient 可注入专用 HTTP 客户端。SDK 复制配置,不修改调用方实例;默认超时 10 秒,可用 context 缩短。禁止自动跟随重定向,避免凭据被转交其他地址。生产配置 HTTPS;SDK 不承担部署 TLS 终止。
健康响应最多 16 KiB,业务响应最多 1 MiB,请求最多 512 KiB。大业务内容应传对象引用。参数/result 使用 json.RawMessage,不转成 float64;revision 在 Go 中为 uint64,JSON 编码为字符串。服务端字段及上限见各接口手册。
## 5. 外部项目本地接入
SDK 尚未发布版本。开发期可以用本地 replace:
```sh
go mod edit -require=git.yuntuo.hk/k2safe/orbit/sdk/go@v0.0.0
go mod edit -replace=git.yuntuo.hk/k2safe/orbit/sdk/go=/absolute/path/to/orbit/sdk/go
go mod tidy
```
将示例路径换成真实路径,不要把本机绝对路径作为发布依赖提交。后续会验证独立 module 标签和真实远端取包,再提供 go get 发布命令。当前源码同时验证 GOWORK=off 的独立构建。
## 6. 查询执行历史与证据
只读凭据需要 tasks:read 和任务所属队列范围。下方为接入函数片段,遍历尝试摘要并查询每条尝试详情;每次页面请求均需检查错误:
```go
pageRequest := orbit.HistoryPageRequest{Limit: 20}
for {
page, err := client.ListTaskAttempts(ctx, taskID, pageRequest)
if err != nil { return err }
for _, summary := range page.Items {
detail, err := client.GetTaskAttempt(ctx, taskID, summary.ID)
if err != nil { return err }
fmt.Println(detail.ID, detail.Epoch, detail.State)
// Result 是 json.RawMessage;读取业务字段时保留精确类型。
}
if page.NextCursor == "" { break }
pageRequest.Cursor = page.NextCursor
}
```
查询证据对应 `ListAttemptEvidence(ctx, taskID, attemptID, pageRequest)` 与 `GetAttemptEvidence(ctx, taskID, attemptID, evidenceID)`,列表相同方式使用 NextCursor。结果正文只在详情返回,列表适合按需展示。查询快照不授予执行权;证据的 outcome 是 Worker 原始声明,EVIDENCE_ONLY 不能当作任务成功。当前权威任务结果用 GetTask 核对。
完整 [执行历史示例](../../sdk/go/examples/history/main.go) 会创建一条模拟任务,提交固定成功结果,再模拟矛盾报告,并通过上述四个查询核对历史。先按 [Worker 初始化步骤](worker.md#1-可运行的文本规范化示例) 准备具有提交、读取及 Worker 权限的专用凭据,再从仓库根目录执行:
```sh
cd sdk/go
ORBIT_URL=http://127.0.0.1:8080 \
ORBIT_CREDENTIALS_FILE=../../.local/worker.credentials.json \
go run ./examples/history
```
预期输出:
```text
task=<任务ID> state=SUCCEEDED attempts=1 evidence=1 reason=RESULT_CONFLICT disposition=EVIDENCE_ONLY
```
示例是受控故障演示,不调用外部业务系统。原结果为 `{"version":"v1","sequence":9007199254740993}`,矛盾内容 `{"version":"v2"}` 只进入证据;任务仍保留原成功结果。每次运行创建独立任务/处理器身份,正常结束会排空并关闭连接,历史保留。示例不自动处理全部网络故障,失败时非零退出;应按输出的稳定错误分类核查,持续消费请使用自动 Worker。
## 7. 后续交付
P2 已提供底层协议、[自动 Worker 运行器及示例](worker-runtime.md) 与历史查询,并通过 [Schema 及进程故障阶段验收](../reports/phase-2.md);P3 已实现 [安全重试](../api/retries.md)、[计划调度](../api/schedules.md)、[运行中取消](../api/cancellation.md) 、[队列资源控制及示例](../api/queues.md) 和 [应用共享配额及示例](../api/application-resources.md),[资源键互斥和单调序号示例](../api/keyed-concurrency.md) 已实现,[优先级场景和节点公平派发](../api/priority-and-fairness.md) 已实现,结果订阅继续开发;P4–P5 提供流程构建发布、信号、等待、轮询与人工恢复。每项随实现同步交付可运行示例及异常回归。
## 订阅管理示例
[完整运行方法](../examples/subscriptions.md) 使用显式 --event-access 凭据,执行创建/同键核对/暂停/恢复/查询,再暂停本次订阅并保留审计。源码见 [examples/subscriptions](../../sdk/go/examples/subscriptions/main.go)。WSS 连接 SDK 与自动消费器见 [消费手册](event-consumer.md),可运行 [协议示例](../examples/event-protocol.md) 验证跨连接 ACK;[持久化 Inbox 示例](../examples/result-inbox.md) 已独立交付,核心SDK不新增数据库驱动。