2c09c61165
将target_project_ids替换为更通用的data_id_filter
110 lines
6.0 KiB
Markdown
110 lines
6.0 KiB
Markdown
# 同步流程(pipeline -> strategy -> datasource)
|
||
|
||
## 1. 全流程主线
|
||
1. pipeline 装配组件并加载持久化。
|
||
2. pipeline 为 datasource 绑定 collection,但不在 bootstrap 阶段全量拉取业务数据。
|
||
3. pipeline 在每个 `node_type` 开始执行前,单独加载该 `node_type` 的最新数据。
|
||
4. pipeline 调用 `strategy.bind()`。
|
||
5. pipeline 调用 `strategy.create()` / `strategy.update()` 生成动作节点。
|
||
6. pipeline 调用 `datasource.sync_all()` 执行动作并回写执行状态。
|
||
7. pipeline 输出统计并持久化。
|
||
|
||
## 2. reset 时序
|
||
|
||
### 2.1 加载时 reset(phase1 语义)
|
||
- 在 `common/collection.py::load_from_persistence()` 执行。
|
||
- 语义:仅恢复持久化状态(不在此阶段做状态归并)。
|
||
|
||
### 2.2 加载后 cleanup(phase2 语义)
|
||
- pipeline 调用 `BaseSyncStrategy.run_reset()`。
|
||
- 实际实现:`strategy_ops/reset_ops.py::run_phase2_cleanup()`。
|
||
- 核心事件:`E01`(`S16 -> S00/S15`)。
|
||
- `S16` 表示“持久化加载输入态”:本轮从持久化恢复出的节点集合(可包含上轮遗留节点,也可包含上轮已稳定节点)。
|
||
- 判定:
|
||
- `is_create_zombie=true` -> `S15`,节点删除(并尝试解绑);
|
||
- `is_create_zombie=false` -> `S00`,节点归并为 `UNCHECKED/NONE/PENDING` 并清空 `error`。
|
||
|
||
### 2.2.1 `enable_persistence` 与 bootstrap 关系
|
||
- `enable_persistence=true`:先 `load_from_persistence()`,再对加载出的节点执行 `E01`(`S16` 域内处理)。
|
||
- `enable_persistence=false`:本轮没有持久化输入,`S16/E01` 不参与;随后 Stage1 新加载节点直接进入本轮 bind/create/update/sync 主流程。
|
||
|
||
### 2.3 加载异常隔离(S17)
|
||
- 持久化中若出现非法枚举值(`action/status/binding_status`),节点标记为 `bootstrap_blocked`(`S17` 语义)。
|
||
- 这类节点保留 `error`,用于人工排查。
|
||
- 这类节点不会进入 `E01`,也不会参与 bind/create/update/sync 自动流程。
|
||
|
||
## 3. bind 流程(strategy_ops)
|
||
- 入口:`strategy_ops/bind_ops.py::run_bind()`
|
||
- 入口状态:`S00`
|
||
|
||
### 核心绑定判定
|
||
- `phase_core_state()` 内触发 `E10`。
|
||
- 有绑定记录:根据本端/对端有效性进入 `S01/S03/S04`。
|
||
- 无绑定记录:进入 `S02`。
|
||
|
||
### 依赖检查
|
||
- `phase_dependency_check()` -> `check_dependencies_for_nodes()` 内触发 `E15`。
|
||
- `data_present=false` -> `S03`。
|
||
- `dep_satisfied=false` -> `S05`。
|
||
- `depend_fields` 为空 -> `S04`(无法自动处理,阻断后续自动创建)。
|
||
|
||
### 自动绑定
|
||
- `phase_auto_binding()` 内触发 `E16`。
|
||
- `ONE_TO_ONE` -> `S01`;`AMBIGUOUS/KEY_MISSING/DATA_MISSING` -> `S04`;`KEY_ID_RESOLVE_FAIL` -> `S05`。
|
||
- `ZERO + create_enabled=true` -> `S13`(`PEER_CREATING/NONE/PENDING`,待对侧创建中间态);`ZERO + create_enabled=false` -> `S04`。
|
||
- `auto_bind=false` 时,`E16` 直接落 `S04`(自动绑定未启用),不会进入自动创建路径。
|
||
|
||
## 4. create/update 准备
|
||
|
||
### create
|
||
- 入口:`strategy_ops/create_ops.py::run_create()`
|
||
- 运行时事件:`E20`(`E21/E22` 为配置保留分支,当前 strategy 未接入自动执行)
|
||
- 运行时入口状态:`S13`
|
||
- 说明:`E16` 负责识别“需自动创建”并将源节点置为 `S13`;业务代码执行对侧 spawn+bind 后,再通过 `E20` 将 `S13` 提交到 `S01`(成功);若 spawn 失败,`E20` 不迁移并保留在 `S13` 等待人工/重试。
|
||
- `data_id` 约束:
|
||
- `S13/S01` 要求源节点 `data_id` 存在(`data_id_exist=true`)。
|
||
- 新创建目标节点在 `S06/S10C` 阶段允许 `data_id` 为空;`CREATE SUCCESS`(`S11C`)必须携带非空 `result_data_id`,否则事件直接报错。
|
||
|
||
### update
|
||
- 入口:`strategy_ops/update_ops.py::run_update()`
|
||
- 事件:`E30`
|
||
- 入口状态(source 节点):`S01`
|
||
- `target_has_data_id=false` 或 `update_id_resolve_ok=false` -> `S08`
|
||
- `has_diff=true` -> `S07`
|
||
|
||
### post-create 归并
|
||
- 入口:`pipeline/full_sync_pipeline.py::normalize_create_success_to_update_entry()`
|
||
- 事件:`E41`
|
||
- 语义:`CREATE` 执行成功后,节点先落 `S11C`(SUCCESS),再归并 `S11C -> S01`,作为同轮 update 起点。
|
||
|
||
## 5. 执行回写(datasource)
|
||
- 入口:`datasource/datasource.py`
|
||
- 事件:`E40C_START/E40C`、`E40U_START/E40U`、`E40D_START/E40D`
|
||
- 当前约束:delete stage 尚未接入 strategy 主流程;若运行时检测到 `S09/DELETE` 节点,DataSource 会显式抛错阻断(避免散落删除执行)。
|
||
- 执行准备入口状态:
|
||
- `CREATE`: `S06`
|
||
- `UPDATE`: `S07`
|
||
- `DELETE`: `S09`
|
||
- `S10` 为执行中状态(由本轮执行产生),执行流转固定为“入口 -> S10 -> 终态”,不再出现入口直接到成功/失败。
|
||
- 结果:
|
||
- `SUCCESS -> S11C | S11U | S11D`(按动作)
|
||
- `FAILED -> S12C | S12U | S12D`(按动作)
|
||
- `IN_PROGRESS -> S10C | S10U | S10D`(按动作,支持异步 polling 闭环)
|
||
- `SKIPPED + action=UPDATE -> S14`
|
||
|
||
## 6. 各阶段入口状态总表
|
||
|
||
| 阶段 | 入口状态 | 说明 |
|
||
|---|---|---|
|
||
| Reset(E01) | `S16` | create_zombie -> `S15`;其余 -> `S00` |
|
||
| Bind(E10/E15/E16) | `S00` | bind 三段统一从 `S00` 进入 |
|
||
| Create Prepare(E20/E21/E22) | `S02` / `S13` | 配置入口含 `S02/S13`;当前 strategy 运行时只处理 `S13` 的 `E20` 提交,`S02` 分支保留未接入 |
|
||
| Post-create Ready(E41) | `S11C` | `CREATE` 成功节点归并到 `S01`,进入同轮 update |
|
||
| Update Prepare(E30) | `S01` | 仅从 NORMAL 继续判定(create 成功先经 E41 归并) |
|
||
| Sync Execute(E40C/U/D) | `S06` / `S07` / `S09` / `S10C` / `S10U` / `S10D` | 执行与回写:按动作分事件;入口先进入 `S10*`,再由 `S10*` 进入 `S11*`/`S12*`;轮询返回 `IN_PROGRESS` 时只记录任务进度,不新增状态迁移;仅 UPDATE 可走 `S14` |
|
||
| 隔离(人工) | `S17` | 不参与自动阶段,仅人工处理 |
|
||
|
||
## 7. 不变量保障
|
||
- 每次事件落地后,`engine/events.py::_apply_decision()` 会执行 `runtime.check_invariants()`。
|
||
- 违反 invariant 直接抛错,终止当前路径。
|