172 lines
12 KiB
Markdown
172 lines
12 KiB
Markdown
# 流程实例、控制、信号与操作审计
|
||
|
||
状态:下表公共 HTTP 与独立 Go SDK 已接入。定义发布见[定义接口](workflow-definitions.md),人工恢复见[恢复接口](workflow-recovery.md),完整运行例子见[并行作业与回执](../examples/workflow.md)。SDK 尚未发布正式版本,服务端与 SDK 应使用同一开发版本。
|
||
|
||
实例筛选分页继续开发;[历史激活、轮次、信号和信号资源审计](workflow-history.md)已接入;[Pulse任务流程来源](task-source.md#5-流程固定来源)已接入。旧冻结回执可能不含新增的activation_sequence,应另读当前步骤详情;当前步骤详情只反映当前激活;旧记录保留在数据库,不能把本页的当前视图当作全部历史。
|
||
|
||
## 1. 路由、权限与 SDK
|
||
|
||
下文 `{id}` 为32位小写十六进制流程实例ID,不是定义ID;身份和命名空间来自凭据。所有读取均检查固定定义引用的全部队列。变更还需要 `Content-Type: application/json`、`Authorization: Bearer <token>` 和一个稳定的 `Idempotency-Key`;键最长128字节,字符规则沿用[任务协议](tasks.md)。请求体最大512 KiB,拒绝重复字段、大小写别名、未声明字段和多余查询参数。
|
||
|
||
| 方法与路径 | 权限 | Go SDK 方法 |
|
||
| --- | --- | --- |
|
||
| `POST /v1/workflows` | `workflows:start`;有任务队列时还需 `tasks:submit` | StartWorkflow |
|
||
| `GET /v1/workflows/{id}` | `workflows:read` | GetWorkflow |
|
||
| `GET /v1/workflows/{id}/steps` | `workflows:read` | GetWorkflowSteps |
|
||
| `GET /v1/workflows/{id}/steps/{key}` | `workflows:read` | GetWorkflowStep |
|
||
| `POST /v1/workflows/{id}/control` | `workflows:control` | ControlWorkflow |
|
||
| `POST /v1/workflows/{id}/signals` | `workflows:signal` | SendWorkflowSignal |
|
||
| `GET /v1/workflows/{id}/signals/{signal}` | `workflows:read` | GetWorkflowSignal |
|
||
| `GET /v1/workflows/{id}/operations` | `workflows:audit:read` | ListWorkflowOperations |
|
||
| `GET /v1/workflows/{id}/operations/{operation}` | `workflows:audit:read` | GetWorkflowOperation |
|
||
|
||
GET成功为200;启动及信号首次受理为201,原键回执为200;控制成功为200。控制响应表示意图已保存,取消结清由后台完成。SDK签名、独立类型及各字段中文说明见[调用方法](../../sdk/go/workflow_instances.go)和[协议类型](../../sdk/go/workflow_instance_types.go)。
|
||
|
||
CLI显式开关分别为:`--workflow-access`(定义读/发布)、`--workflow-run-access`(实例读/启动)、`--workflow-control-access`(实例读/控制)、`--workflow-signal-access`(实例读/信号)、`--workflow-recovery-access`(实例读/恢复)、`--workflow-audit-access`(流程操作审计读)。普通 Worker、定义发布及任务核查权限均不会自动获得流程管理权限。初始化会先验证权限集合再交付凭据,具体命令见[示例](../examples/workflow.md)。
|
||
|
||
## 2. 固定版本启动
|
||
|
||
`StartWorkflow(ctx, key, StartWorkflowRequest)` 的请求:
|
||
|
||
```json
|
||
{
|
||
"definition_id": "11111111111111111111111111111111",
|
||
"version": "v1",
|
||
"input": {"n": 9007199254740993},
|
||
"business_key": "operation-001 "
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型与约束 |
|
||
| --- | --- |
|
||
| definition_id | 必填,当前命名空间的定义ID |
|
||
| version | 必填,1–64个ASCII版本字符,首字符字母或数字,之后还可用 `_ . -`;不解析latest |
|
||
| input | 必填,最多256 KiB JSON,必须符合固定版本输入契约;显式null与缺失不同,数字不经过float64 |
|
||
| business_key | 可选,默认空字符串,最多191个Unicode字符;尾部空格保留,不能替代幂等键 |
|
||
|
||
示意完整回执:
|
||
|
||
```json
|
||
{
|
||
"request_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||
"data": {
|
||
"instance": {
|
||
"id": "22222222222222222222222222222222",
|
||
"namespace_id": "33333333333333333333333333333333",
|
||
"definition_id": "11111111111111111111111111111111",
|
||
"definition_version_id": "44444444444444444444444444444444",
|
||
"version": "v1",
|
||
"state": "RUNNING",
|
||
"revision": "2",
|
||
"paused": false,
|
||
"control_revision": "1",
|
||
"input": {"n": 9007199254740993},
|
||
"business_key": "operation-001 ",
|
||
"deadline_at": "2026-09-18T08:01:00Z",
|
||
"created_at": "2026-09-18T08:00:00Z",
|
||
"updated_at": "2026-09-18T08:00:00Z"
|
||
},
|
||
"deduplicated": false
|
||
}
|
||
}
|
||
```
|
||
|
||
`GetWorkflow`的data直接是instance对象。可能状态为RUNNING、WAITING、CANCELLING、NEEDS_REVIEW、SUCCEEDED、FAILED、CANCELLED;paused是独立标记。`output`在存在结果时返回,成功输出可以为显式null。`cancel_requested_at`、`stop_kind`(CANCEL/FAILURE)、`stop_requested_at`、`completed_at`仅有值时返回。所有时间为UTC RFC3339,revision及control_revision为十进制字符串,SDK使用uint64。
|
||
|
||
启动固定定义版本和总截止,并在同事务创建门控、步骤和首批任务。原键同内容返回**首次受理快照**,不重算时间,不代表当前状态;同键不同内容返回IDEMPOTENCY_CONFLICT。网络响应丢失时保持原键和原请求核对,再用GetWorkflow读取当前状态。每命名空间最多10000个未终结实例,已保存的原回执在满额时仍可恢复。
|
||
|
||
## 3. 步骤及当前激活
|
||
|
||
GetWorkflowSteps返回 `{instance_id, revision, steps}`,steps按key排序、最多128项,不含内部根步骤。每项含 `id/key/kind/state/revision`;已激活时还含 `activation_id/activation_sequence`,TASK还含直接 `task_id`。未激活步骤没有激活ID和代次。步骤状态包括BLOCKED、ACTIVE、WAITING、SUCCEEDED、FAILED、CANCELLED、NEEDS_REVIEW、SKIPPED。
|
||
|
||
GetWorkflowStep返回单个步骤详情,实例revision与当前步骤同事务读取:
|
||
|
||
```json
|
||
{
|
||
"request_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||
"data": {
|
||
"instance_id": "22222222222222222222222222222222",
|
||
"revision": "8",
|
||
"step": {
|
||
"id": "55555555555555555555555555555555",
|
||
"key": "receipt",
|
||
"kind": "SIGNAL",
|
||
"state": "WAITING",
|
||
"revision": "2",
|
||
"activation_id": "66666666666666666666666666666666",
|
||
"activation_sequence": 1
|
||
},
|
||
"input": {"name": "done", "payload_version": "v1", "correlation": "operation-001 "},
|
||
"activated_at": "2026-09-18T08:00:05Z",
|
||
"wait": {
|
||
"id": "77777777777777777777777777777777",
|
||
"kind": "SIGNAL",
|
||
"state": "WAITING",
|
||
"name": "done",
|
||
"payload_version": "v1",
|
||
"correlation_key": "operation-001 ",
|
||
"deadline_at": "2026-09-18T08:00:35Z"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
- `input/output`属于当前激活,每次只读取一份;未激活或尚无输出时省略,显式null保留。`activated_at/completed_at`属于当前激活,不能据新激活时间重算原预算。
|
||
- POLL的 `poll` 包含 used_rounds、first_round、first_round_attempts_used、max_rounds、max_attempts_per_round、interval_ms、deadline_at、last_task_id;current_task_id、next_poll_at、resolved_at在有值时返回。last_task_id指当前激活最后业务轮任务,可再通过GetTask读取其状态/版本。
|
||
- SIGNAL、TIMER和有最终信号的POLL返回 `wait`,包含当前等待身份、类型、状态、原截止和关联;name/payload_version不适用于TIMER,旧未核验等待也可能缺失。winner_signal_id和resolved_at在有值时返回。已选中赢家不代表在途任务已结清。
|
||
- 时间预算不会随人工换代增加。信号发送者应读取activation_sequence,不能把激活ID、步骤revision或任务尝试epoch当作等待代次。
|
||
|
||
## 4. 暂停、继续与取消
|
||
|
||
`ControlWorkflow(ctx, id, key, WorkflowControlRequest)`:
|
||
|
||
```json
|
||
{"operation":"PAUSE","expected_control_revision":"1","reason":"维护期间停止推进新工作"}
|
||
```
|
||
|
||
operation必填,为PAUSE/RESUME/CANCEL;expected_control_revision为读取到的非零control_revision字符串,reason为1–1024个Unicode字符,不允许全空白或NUL。成功data为 `{instance, deduplicated}`,instance字段同启动回执。新决定使用旧控制版本返回STATE_CONFLICT;原键恢复仍返回第一次的冻结决定。
|
||
|
||
PAUSE关闭新执行授权,在途结果继续收集;RESUME不清除NEEDS_REVIEW,不撤销首次停止目标,不延长原截止。CANCEL保存取消意图并停止后继,保留在途许可直到真实执行结束;未知效果仍进入核查。后台任务结果改变通用revision,不要求操作者追逐每个结果去更新control_revision。详细结清规则见[控制设计](../15-workflow-controls.md)。
|
||
|
||
## 5. 有身份的外部信号
|
||
|
||
`SendWorkflowSignal(ctx, id, key, SendWorkflowSignalRequest)`:
|
||
|
||
```json
|
||
{
|
||
"name":"done",
|
||
"payload_version":"v1",
|
||
"target_step_key":"receipt",
|
||
"target_activation_sequence":1,
|
||
"correlation_key":"operation-001 ",
|
||
"payload":{"n":9007199254740993},
|
||
"reason":"已核验外部回执",
|
||
"evidence_ref":"evidence:receipt-001"
|
||
}
|
||
```
|
||
|
||
name/payload_version/target_step_key必填,分别最多128/32/64个ASCII名称字符;代次为非零uint32数字。correlation_key为1–512字节UTF8、精确匹配并保留尾部空格。payload必填、最多256 KiB,符合固定契约时可显式null。reason规则同控制原因;evidence_ref可选、最多512个Unicode字符,不含空白或控制字符,平台不会访问这个引用。
|
||
|
||
成功data为 `{signal, deduplicated}`。signal字段:id、namespace_id、workflow_id、revision字符串、name、payload_version、target_step_key、target_activation_sequence、correlation_key、payload、actor_id、state、accepted_at、expires_at;evidence_ref、disposition、consumed_wait_id在有值时返回。actor_id从认证获得。GetWorkflowSignal直接返回当前signal对象。
|
||
|
||
受理与消费分离:PENDING可以稍后变为CONSUMED、REJECTED或EXPIRED。每实例全部历史受理记录最多1024条,原键回执先于上限检查。早到信号可以指定首次代次1;当前旧代次信号保存为REJECTED/STALE_ACTIVATION,未来代次冲突。恢复为新代次后,原信号原键仍返回旧回执,不能用重报改变目标。最终查询与信号按原事件时间竞争,PENDING查询不争夺业务完成权,见[信号设计](../14-workflow-signals.md)。
|
||
|
||
## 6. 操作审计与错误处理
|
||
|
||
ListWorkflowOperations接受HistoryPageRequest:limit默认20、范围1–100;cursor最大1024字节,绑定命名空间、流程ID和查询种类,不可跨资源复用。data为 `{items, next_cursor?}`;每项含 id、workflow_id、operation_id、actor_id、action、created_at,按时间及ID倒序。GetWorkflowOperation除这些字段外还返回reason、evidence_ref(可空省略)、before、after JSON摘要。单独读取正文,避免列表聚合大结果。
|
||
|
||
该接口当前查询resource_kind=workflow的启动、推进、控制和恢复审计;独立任务核查审计通过恢复回执的task_audit_id关联。信号自身的受理状态通过GetWorkflowSignal读取;[信号资源审计及历史激活查询](workflow-history.md)使用独立路由,统一状态事件时间线仍待核对交付。
|
||
|
||
| HTTP/错误码 | 处理方式 |
|
||
| --- | --- |
|
||
| 400 INVALID_ARGUMENT | 修正字段、固定契约或查询游标;不要把遗漏声明默认成true |
|
||
| 401 UNAUTHENTICATED / 403 PERMISSION_DENIED | 核对凭据和显式动作权限,重报不会绕过撤权 |
|
||
| 404 NOT_FOUND | 资源不存在、跨命名空间或队列不在授权范围 |
|
||
| 409 STATE_CONFLICT / IDEMPOTENCY_CONFLICT | 当前状态/版本不符或原键请求改变;先读取权威状态 |
|
||
| 409 WORKFLOW_INSTANCE_LIMIT / WORKFLOW_SIGNAL_LIMIT | 固定资源数量上限,不能通过新键盲目补发 |
|
||
| 429 QUEUE_FULL / APPLICATION_FULL | 新工作配额不足;保持原请求身份核对,服务端给Retry-After |
|
||
| 413 BODY_TOO_LARGE / 415 UNSUPPORTED_MEDIA_TYPE | 缩小请求或使用application/json |
|
||
| 503 UNAVAILABLE / 网络异常 | 提交结果可能不明,保持原键和原命令核对;SDK不自动换键 |
|
||
|
||
已实现路由之外的路径为404。回归证据和剩余交付范围见[公共接入报告](../reports/phase-5-public-api.md)。
|