9.0 KiB
流程定义与不可变版本
状态:P4 定义校验、持久化发布及独立 Go SDK 已实现;实例启动、控制、等待和恢复已接入实例API及恢复API。规则格式见结构版本1,可运行源码及命令见研发发布场景。
1. 权限、传输与范围
使用 HTTPS、Authorization: Bearer <token>、统一 request_id 信封。POST 必须有唯一 Idempotency-Key 头及 Content-Type: application/json。请求体最多512 KiB,完整定义编码最多256 KiB,JSON总深度最多32;拒绝未知字段、大小写别名、重复字段、非法Unicode、无效数字和不符合类型的null。
| 接口 | 权限 | 范围 |
|---|---|---|
POST /v1/workflow-definitions |
workflows:definitions:publish |
当前凭据命名空间 |
GET /v1/workflow-definitions/{definition_id} |
workflows:definitions:read |
当前命名空间元数据,不返回规则 |
POST /v1/workflow-definitions/{definition_id}/versions |
workflows:definitions:publish |
定义及其引用的全部队列 |
GET /v1/workflow-definitions/{definition_id}/versions/{version} |
workflows:definitions:read |
定义及其引用的全部队列 |
发布与完整版本读取均在事务中核对队列存在、命名空间归属及当前凭据队列范围。发布不要求tasks:submit,不创建任务;发布者可以与运行方分权。默认Bootstrap凭据没有流程权限,显式--workflow-access才增加上述两个动作。读取元数据只受命名空间级定义权限限制。
GET不接受查询参数。当前没有定义列表、修改、删除或latest接口;调用方保存创建回执中的定义ID,并显式使用版本名。
2. 创建定义
POST /v1/workflow-definitions
| 字段 | 类型 | 规则 |
|---|---|---|
| name | string | 必填,1–128 ASCII字符;首位字母或数字,其余可含.、_、-;同命名空间唯一且区分大小写 |
| description | string | 可省略为空,最多1024个Unicode字符,不允许NUL |
{"name":"object.pipeline","description":"通用对象作业"}
首次创建201,原键重报200。回执示意(实际ID、时间由服务端生成):
{
"request_id":"0123456789abcdef0123456789abcdef",
"data":{
"definition":{
"id":"1123456789abcdef0123456789abcdef",
"namespace_id":"2123456789abcdef0123456789abcdef",
"name":"object.pipeline",
"description":"通用对象作业",
"revision":"1",
"created_at":"2026-09-18T00:00:00Z",
"updated_at":"2026-09-18T00:00:00Z"
},
"deduplicated":false
}
}
GET /v1/workflow-definitions/{definition_id}的data直接返回上述definition对象。revision为字符串编码的uint64,初始1,每个新版本发布增加1。名称和说明在本阶段没有修改入口。原创建回执保留创建时的revision,当前值通过GET查询。
每个命名空间最多100个定义。不同键重用同一名称返回409;恢复创建结果必须使用原键,不能用名称猜测操作是否成功。
3. 发布版本
POST /v1/workflow-definitions/{definition_id}/versions
| 字段 | 类型 | 规则 |
|---|---|---|
| version | string | 必填,1–64 ASCII字符,名称规则同上;研发指定的业务版本名,不与schema_version混用 |
| specification | object | 必填,完整结构版本1定义;所有生效任务策略显式冻结 |
| reason | string | 必填非空白,最多1024个Unicode字符,不允许NUL,写入发布审计 |
最小定义直接返回输入,可用于验证发布链路:
{
"version":"v1",
"reason":"initial developer release",
"specification":{
"schema_version":1,
"input_type":{"kind":"STRING"},
"timeout_ms":60000,
"failure_policy":"REVIEW",
"body":{
"output_type":{"kind":"STRING"},
"output":{"kind":"REFERENCE","reference":{"source":"input"}}
}
}
}
首次发布201;原键重报或不同键的同版本同内容发布200。信封data为:
{
"version":{
"id":"3123456789abcdef0123456789abcdef",
"namespace_id":"2123456789abcdef0123456789abcdef",
"definition_id":"1123456789abcdef0123456789abcdef",
"version":"v1",
"specification":{
"schema_version":1,
"input_type":{"kind":"STRING"},
"timeout_ms":60000,
"failure_policy":"REVIEW",
"body":{
"output_type":{"kind":"STRING"},
"output":{"kind":"REFERENCE","reference":{"source":"input"}}
}
},
"content_digest":"0000000000000000000000000000000000000000000000000000000000000000",
"published_by":"4123456789abcdef0123456789abcdef",
"published_at":"2026-09-18T00:00:00Z",
"analysis":{"steps":0,"max_concurrency":0,"max_task_attempts":0,"queues":[]}
},
"deduplicated":false
}
示意中的全零摘要不是上述请求的实际摘要。实际content_digest为64位小写十六进制SHA-256:对已校验结构的规范JSON加域前缀orbit.weave.spec.v1\0后计算。对象键顺序、数字的等值十进制表示不影响内容比较;数组顺序属于内容,包括枚举/状态分组数组。数字全程保留精度,不使用float64生成内容摘要。
published_by是最初发布凭据ID,published_at是原始数据库UTC时间;重复发布不改写。analysis按全部静态路径保守计算节点、并发与任务尝试上界,队列排序去重且始终为数组。它不是运行用量或已授予配额。
每个定义最多100个版本。达到上限仍可原键核对和同版本同内容确认。发布v2不改写v1。数据库不可变触发器拒绝UPDATE,关联关系由事务校验,无外键、无级联删除。
4. 幂等、并发及未知结果
- 创建操作按命名空间和
workflow.definition.create隔离;发布按命名空间、workflow.version.publish及定义ID隔离。幂等键格式和90天保留窗口沿用公共规则。 - 原键绑定整个命令,包括
reason。原键不同内容为IDEMPOTENCY_CONFLICT;换键不允许覆盖已存在版本,不同规则为STATE_CONFLICT。 - 不同键、相同版本及相同规则返回第一次的版本。后续请求的原因不替换原审计,不增加父定义revision,不重复产生发布审计。
- 并发控制顺序为认证共享锁→应用额度行→操作身份→定义行→排序后的引用队列。定义、版本、父定义revision、审计和幂等回执同事务提交,审计失败全部回滚。
- 任何超时、连接中断或503都可能发生在提交前后。保留原ID、版本、内容、原因和键核对,禁止生成新身份或盲目修改规则重发。
- 每次重报仍核对当前权限和引用队列;权限被收回、队列缺失时不得用旧回执绕过。版本读取还验证存储原文、结构版本和内容摘要,损坏或不兼容数据返回503,不能默默忽略后继续使用。
5. 读取与错误
GET /v1/workflow-definitions/{definition_id}/versions/{version}的data直接返回上述version对象,200。输入版本名被严格限制,不能携带路径片段。
| 状态 / code | 处理 |
|---|---|
| 400 / INVALID_ARGUMENT | 修正结构、引用、类型、预算或字段;此校验拒绝不发布版本 |
| 401 / UNAUTHENTICATED | 核对凭据与有效期 |
| 403 / PERMISSION_DENIED | 缺少定义动作权限 |
| 404 / NOT_FOUND | 定义/版本/队列不存在、不同命名空间或队列范围不允许;不据此猜测他人资源 |
| 409 / IDEMPOTENCY_CONFLICT | 原键绑定不同命令;回查原操作,不直接换键 |
| 409 / STATE_CONFLICT | 名称冲突或同版本不同规则;有意更新需显式发布新版本 |
| 409 / WORKFLOW_DEFINITION_LIMIT | 命名空间达到100个定义,原创建回执仍可恢复 |
| 409 / WORKFLOW_VERSION_LIMIT | 定义达到100个版本,旧版本确认与读取不受此上限影响 |
| 413 / BODY_TOO_LARGE | 整个HTTP请求超过512 KiB |
| 415 / UNSUPPORTED_MEDIA_TYPE | 必须使用application/json |
| 503 / UNAVAILABLE | 服务/事务/存储完整性异常,原身份核对;持续异常需要运维核查 |
6. SDK
独立module为git.yuntuo.hk/k2safe/orbit/sdk/go,无服务端模型、数据库或ORM依赖。
| 方法 | 输入 → 返回 |
|---|---|
CreateWorkflowDefinition(ctx,key,in) |
CreateWorkflowDefinitionRequest → WorkflowDefinitionResult |
GetWorkflowDefinition(ctx,id) |
定义ID → WorkflowDefinition |
PublishWorkflowVersion(ctx,id,key,in) |
PublishWorkflowVersionRequest → WorkflowVersionResult |
GetWorkflowVersion(ctx,id,version) |
定义ID及固定版本 → WorkflowVersion |
WorkflowRef(source,path...) |
构造有类型校验的引用表达式;发布时校验作用域 |
规则通过WorkflowSpecification、WorkflowStep等强类型结构构建,常量使用json.RawMessage,避免把大整数先转float64。SDK不复制服务端完整校验器;发布返回权威校验结果。网络错误不会自动重试发布,也不自动变更版本。完整示例见发布场景。