Files
orbit/docs/api/workflow-definitions.md

160 lines
9.0 KiB
Markdown
Raw Permalink 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.
# 流程定义与不可变版本
状态:P4 定义校验、持久化发布及独立 Go SDK 已实现;实例启动、控制、等待和恢复已接入[实例API](workflows.md)及[恢复API](workflow-recovery.md)。规则格式见[结构版本1](workflow-definition-format.md),可运行源码及命令见[研发发布场景](../examples/workflow-definition.md)。
## 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 |
```json
{"name":"object.pipeline","description":"通用对象作业"}
```
首次创建201,原键重报200。回执示意(实际ID、时间由服务端生成):
```json
{
"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,写入发布审计 |
最小定义直接返回输入,可用于验证发布链路:
```json
{
"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`为:
```json
{
"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天保留窗口沿用[公共规则](tasks.md)。
- 原键绑定整个命令,包括`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不复制服务端完整校验器;发布返回权威校验结果。网络错误不会自动重试发布,也不自动变更版本。完整示例见[发布场景](../examples/workflow-definition.md)。