feat: deliver authenticated task APIs, SDK and P1 regression
This commit is contained in:
@@ -1,57 +1,127 @@
|
||||
# Go SDK 接入说明
|
||||
|
||||
当前已实现客户端创建、存活与就绪查询。任务提交、Worker 和流程构建接口按开发计划逐阶段实现。
|
||||
已实现健康查询、任务提交/查询/分页/待执行取消、队列创建/查询。Worker 和流程构建接口按 [开发计划](../08-development-plan.md) 继续实现。
|
||||
|
||||
SDK module:`git.yuntuo.hk/k2safe/orbit/sdk/go`。服务端与 SDK 在同一 Git 仓库,使用独立 `go.mod`;SDK 当前仅依赖 Go 标准库。
|
||||
module:`git.yuntuo.hk/k2safe/orbit/sdk/go`。SDK 使用独立 go.mod,当前仅依赖 Go 标准库,不引用服务端模型或数据库实现。
|
||||
|
||||
## 1. 本地运行当前示例
|
||||
## 1. 从初始化到运行示例
|
||||
|
||||
前置条件:Go 1.27.1、MySQL 8.4+,先按项目根目录 README 迁移数据库并启动服务。
|
||||
需要 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
|
||||
```
|
||||
|
||||
[完整示例源码](../../sdk/go/examples/health/main.go)。示例 context 最多等待 5 秒;数据库或迁移未就绪时返回错误并以非零状态退出。
|
||||
重复运行示例会新建一个独立任务并取消它,listed 数量可能增加,最多显示当前页 10 条。数据和审计保留,不执行硬删除。示例只演示受理闭环,尚不执行文件转换。
|
||||
|
||||
## 2. 当前真实调用方式
|
||||
- [健康示例源码](../../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("http://127.0.0.1:8080", orbit.Options{})
|
||||
client, err := orbit.NewClient(baseURL, orbit.Options{Token: token})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
health, err := client.Readiness(ctx)
|
||||
// 应先把 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 {
|
||||
var responseErr *orbit.HTTPError
|
||||
if errors.As(err, &responseErr) {
|
||||
// responseErr.StatusCode 是实际 HTTP 状态,例如 503。
|
||||
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(health.Status, health.Scope)
|
||||
fmt.Println(cancelled.Task.State)
|
||||
```
|
||||
|
||||
片段需在调用函数中使用并导入标准库包和 `orbit`;完整可运行程序见上方源码。
|
||||
取消重报必须保留第一次取消时的 expected_revision,不能将响应中的新版本塞回同一幂等请求。当前只取消 WAITING 且不归属流程的任务。
|
||||
|
||||
`Options.HTTPClient` 可注入专用 HTTP 客户端。SDK 复制其配置,不修改调用方客户端;禁止自动跟随重定向,限制健康响应大小,不自动重试请求,不将服务端响应正文放进错误。
|
||||
业务错误返回 *orbit.APIError,支持 errors.As 转为 *orbit.HTTPError 查看状态。健康错误或无法识别的网关错误使用 *orbit.HTTPError,不带未知响应正文。网络/上下文错误按标准库错误返回;超时并不能证明服务端没有提交。
|
||||
|
||||
## 3. 外部项目的本地接入
|
||||
## 4. 方法与限制
|
||||
|
||||
仓库尚未发布 SDK 版本。开发期间可使用独立工作区或本地 replace,例如在接入项目中执行:
|
||||
| 方法 | 请求 / 返回 | 文档 |
|
||||
| --- | --- | --- |
|
||||
| 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) |
|
||||
|
||||
所有方法第一个参数为 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
|
||||
@@ -59,14 +129,8 @@ go mod edit -replace=git.yuntuo.hk/k2safe/orbit/sdk/go=/absolute/path/to/orbit/s
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
示例路径需替换为本机实际目录。不要将本机绝对路径 replace 提交为发布依赖。后续发布 SDK 时使用独立 module 标签与兼容说明,在真实仓库取包路径验证后给出 `go get` 命令;当前不提供不存在的发行版本。
|
||||
将示例路径换成真实路径,不要把本机绝对路径作为发布依赖提交。后续会验证独立 module 标签和真实远端取包,再提供 go get 发布命令。当前源码同时验证 GOWORK=off 的独立构建。
|
||||
|
||||
## 4. 后续 SDK 交付
|
||||
## 6. 后续交付
|
||||
|
||||
- P1:凭据配置、幂等提交、查询与待执行取消。
|
||||
- P2:处理器注册、Worker 容量、WSS、续租与结果确认、优雅退出。
|
||||
- P3:计划管理、可靠结果订阅与队列控制。
|
||||
- P4:流程定义、发布、启动、信号与查询。
|
||||
- P5:有界查询、暂停继续和人工恢复入口。
|
||||
|
||||
每阶段同步更新可运行场景、错误处理与兼容测试。业务幂等、外部结果核查与 Outbox 接入责任会与真实代码示例一起说明。
|
||||
P2 提供 Worker 注册、WSS、能力/容量、执行确认、续租和排空;P3 提供计划与结果订阅;P4–P5 提供流程构建发布、信号、等待、轮询与人工恢复。每项随实现同步交付可运行示例及异常回归。
|
||||
|
||||
Reference in New Issue
Block a user