更新文档

This commit is contained in:
strepsiades
2026-03-25 10:32:50 +08:00
parent 67370657db
commit 4b81b83fd8
5 changed files with 208 additions and 29 deletions
+53 -2
View File
@@ -2,6 +2,42 @@
可作为命令行工具运行,也可作为 `pip install -e .` 的本地可编辑安装库接入其他项目。
## 0. 10 分钟上手
如果你是第一次进入这个仓库,先不要从所有文档开始读,先确认环境和最小工具链可用。
推荐顺序:
1. 准备 Python 3.9+ 环境(当前仓库已在 `pyproject.toml` 中声明 `requires-python >= 3.9`)。
2. 在仓库根目录创建并激活虚拟环境。
3. 以可编辑模式安装本项目。
4. 先跑配置校验,再跑一个轻量集成测试,确认本地环境可用。
5. 只在确认入口可运行后,再去看架构与状态机文档。
最小命令链:
```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .
python run.py --help
python tools/validate_config.py --config sync_state_machine/config/node_state_machine.yaml
pytest tests/integration/test_toolchain_config_and_graph.py -q
```
如果你只是想直接运行仓库内现成配置,优先用仓库入口:
```bash
python run.py --config_path=run_profiles/preset/jsonl_to_jsonl.default.yaml
```
如果你已经完成 `pip install -e .`,也可以使用安装后的命令行入口:
```bash
ecm-sync-run --config_path=run_profiles/preset/jsonl_to_jsonl.default.yaml
```
面向第一次接触仓库的更完整说明见:`docs/getting_started.md`
## 1. 项目简介
本项目用于实现异构系统之间的数据推送:将项目侧管理平台的十余种业务数据,稳定推送到集团侧管理平台。
@@ -18,6 +54,7 @@
项目采用:`schema` 严格约束 + 状态机 + 节点模型 + 分层架构 + 注册式 `domain` + 数据源与同步系统解耦。
架构详见:
- `docs/getting_started.md`
- `docs/architecture.md`
- `docs/node_state_definition.md`
- `docs/state_machine.md`
@@ -58,20 +95,24 @@
## 5. 使用方法
先区分两种常见使用方式:
- 仓库内开发与调试:优先使用 `python run.py ...`,因为它不依赖 shell 中已经存在 `ecm-sync-run`
- 作为库或已安装命令使用:先执行 `pip install -e .`,再使用 `ecm-sync-run ...`
运行配置遵循一个约定:
- 跟踪在仓库里的 `run_profiles/*.yaml``run_profiles/preset/*.default.yaml` 只写必要的覆盖项。
- pipeline 启动时会打印并写入一份 **Resolved Full Config**,把省略的默认值全部补齐,便于排障和审阅。
- 字段含义与全量示例见:`docs/runtime_config_guide.md`
### JSONL 同步
- 已安装命令行入口:`ecm-sync-run --config_path=run_profiles/preset/jsonl_to_jsonl.default.yaml`
- 仓库内直接运行:`python run.py --config_path=run_profiles/preset/jsonl_to_jsonl.default.yaml`
- 已安装命令行入口:`ecm-sync-run --config_path=run_profiles/preset/jsonl_to_jsonl.default.yaml`
- 多项目 JSONL 示例:`python run.py --config_path=run_profiles/preset/jsonl_to_jsonl.multi_project.default.yaml`
- 自定义配置:从 `run_profiles/preset/` 复制一份到 `run_profiles/*.local.yaml`,只改有差异的字段即可。
### API 同步
- 已安装命令行入口:`ecm-sync-run --config_path=run_profiles/preset/jsonl_to_api.default.yaml`
- 仓库内直接运行:`python run.py --config_path=run_profiles/preset/jsonl_to_api.default.yaml`
- 已安装命令行入口:`ecm-sync-run --config_path=run_profiles/preset/jsonl_to_api.default.yaml`
- 如果是单项目联调,优先参考仓库内现成示例:`run_profiles/jsonl_to_api.yaml`
### 库模式使用
@@ -99,6 +140,16 @@
## 文档导航
如果你是按任务查文档,建议按下面的顺序进入:
- 第一次接手仓库:`docs/getting_started.md`
- 想理解整体分层:`docs/architecture.md`
- 想理解状态与迁移:`docs/node_state_definition.md` + `docs/state_machine.md`
- 想调运行配置:`docs/runtime_config_guide.md` + `run_profiles/README.md`
- 想接新数据源或改 handler`sync_state_machine/datasource/README.md` + `docs/library_integration_guide.md`
- 想排障:`docs/operations.md`
- 想补测试或跑联调:`docs/testing_guide.md` + `tests/README.md`
- 新人上手:`docs/getting_started.md`
- 总体架构:`docs/architecture.md`
- 状态定义:`docs/node_state_definition.md`
- 状态机规则:`docs/state_machine.md`
+8 -8
View File
@@ -3,7 +3,7 @@
## 1. 分层职责(pipeline + strategy + datasource + domain
### pipeline(编排层)
- 入口:`pipeline/full_sync_pipeline.py`
- 入口:`sync_state_machine/pipeline/full_sync_pipeline.py`
- 负责组装并驱动整条流程:加载持久化、执行 bind/create/update、调用 datasource 同步、持久化结果。
- reset 语义:
- 加载阶段仅恢复持久化状态(不做状态重置);
@@ -24,8 +24,8 @@
- 非僵尸节点统一进入 `S00`,再进入本轮 bind/create/update 判定。
### strategy(决策组织层)
- 外部入口:`sync_system/strategy.py`
- 具体实现下沉:`sync_system/strategy_ops/`
- 外部入口:`sync_state_machine/sync_system/strategy.py`
- 具体实现下沉:`sync_state_machine/sync_system/strategy_ops/`
- `bind_ops.py`: `run_bind()` + `phase_core_state()/phase_dependency_check()/phase_auto_binding()`
- `create_ops.py`: `run_create()`
- `update_ops.py`: `run_update()`
@@ -34,19 +34,19 @@
- strategy 负责收集上下文并调用状态机事件函数,不直接硬编码状态值。
### datasource(执行与回写层)
- 入口:`datasource/datasource.py`
- 入口:`sync_state_machine/datasource/datasource.py`
- 执行 handlercreate/update/delete),并结合 `E40` 将执行结果落地到节点状态。
### domain(业务适配层)
- 目录:`domain/*`
- 目录:`sync_state_machine/domain/*`
- 负责业务字段映射、handler 细节与 schema 约束,不承担状态迁移判定。
## 2. 运行时契约(Runtime Contract
### 真源
- 状态机配置真源:`config/node_state_machine.yaml`
- 事件执行入口:`engine/events.py`
- 状态落地入口:`engine/state_apply.py`
- 状态机配置真源:`sync_state_machine/config/node_state_machine.yaml`
- 事件执行入口:`sync_state_machine/engine/events.py`
- 状态落地入口:`sync_state_machine/engine/state_apply.py`
### 执行规则
1. 业务层构造 `context`
+128
View File
@@ -0,0 +1,128 @@
# 快速上手
这份文档只服务第一次接手 `ecm_sync_system` 的开发者。目标不是完整讲架构,而是让你先跑起来、知道从哪里入手,再去看更细的说明。
## 1. 先做什么
第一次进入仓库时,建议按下面顺序执行:
1. 准备 Python 3.9+。
2. 在仓库根目录创建并激活虚拟环境。
3. 执行 `pip install -e .` 安装当前项目。
4. 跑状态机配置校验,确认基础工具链正常。
5. 跑一条轻量测试,确认测试与渲染工具链可用。
6. 再去看架构文档和状态机文档。
推荐命令:
```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .
python run.py --help
python tools/validate_config.py --config sync_state_machine/config/node_state_machine.yaml
pytest tests/integration/test_toolchain_config_and_graph.py -q
```
## 2. 仓库里最重要的目录
- `sync_state_machine/`
- 真正的引擎实现目录。大多数“核心代码入口”都在这里。
- `run_profiles/`
- 运行配置与模板。
- `tests/`
- 单元测试与集成测试。
- `tools/`
- 状态机校验、图渲染、远程环境等工具。
- `scripts/`
- 自动化测试编排和数据集相关脚本。
- `docs/`
- 面向开发者的设计、运行和排障文档。
## 3. 先读哪几篇文档
按任务来看:
- 想知道系统整体怎么分层:`docs/architecture.md`
- 想知道状态机怎么工作:`docs/node_state_definition.md``docs/state_machine.md`
- 想知道一次同步是怎么跑的:`docs/sync_flow.md`
- 想调运行配置:`docs/runtime_config_guide.md`
- 想接新 datasource 或 handler`sync_state_machine/datasource/README.md``docs/library_integration_guide.md`
- 想看测试体系:`docs/testing_guide.md``tests/README.md`
- 想做排障:`docs/operations.md`
## 4. 新人最容易踩的坑
### 4.1 先用仓库入口,不要默认 shell 里已经有命令
如果你还没执行过 `pip install -e .`,那么 `ecm-sync-run` 不一定可用。
首次调试建议优先用:
```bash
python run.py --config_path=run_profiles/preset/jsonl_to_jsonl.default.yaml
```
安装完成后,再切换到:
```bash
ecm-sync-run --config_path=run_profiles/preset/jsonl_to_jsonl.default.yaml
```
### 4.2 核心实现路径以 `sync_state_machine/` 为准
阅读历史文档时,如果看到类似下面的写法:
- `pipeline/full_sync_pipeline.py`
- `sync_system/strategy.py`
- `datasource/datasource.py`
- `engine/events.py`
请优先理解为它们在当前仓库中的真实位置分别是:
- `sync_state_machine/pipeline/full_sync_pipeline.py`
- `sync_state_machine/sync_system/strategy.py`
- `sync_state_machine/datasource/datasource.py`
- `sync_state_machine/engine/events.py`
## 5. 如果你要开始改代码
### 5.1 改 domain 行为
优先查看:
- `sync_state_machine/domain/<node_type>/`
- `sync_state_machine/sync_system/strategy_ops/`
- `tests/unit/` 中对应测试
### 5.2 改状态机语义
优先查看:
- `sync_state_machine/config/node_state_machine.yaml`
- `sync_state_machine/engine/events.py`
- `sync_state_machine/engine/state_apply.py`
改完建议至少执行:
```bash
python tools/validate_config.py --config sync_state_machine/config/node_state_machine.yaml
pytest tests/integration/test_toolchain_config_and_graph.py -q
```
### 5.3 改运行配置或 datasource
优先查看:
- `docs/runtime_config_guide.md`
- `run_profiles/README.md`
- `sync_state_machine/datasource/README.md`
## 6. 出错先看哪里
推荐排查顺序:
1. 先看运行日志中的 `Resolved Full Config`
2. 再看节点 `sync_log / status / error`
3. 再对照 `docs/operations.md``docs/state_machine.md`
4. 如果是配置问题,先让校验报错,不要绕过 schema 或状态机校验。
+11 -11
View File
@@ -25,17 +25,17 @@
## 3. 事件到代码映射
### bootstrap
- `E01``engine/events.py::e01_bootstrap()`
- `E01``sync_state_machine/engine/events.py::e01_bootstrap()`
### bind
- `E10``engine/events.py::e10_bind_core()`
- `E15``engine/events.py::e15_bind_dependency()`
- `E16``engine/events.py::e16_bind_auto()`(自动绑定判定;`ZERO+create_enabled=true` 时进入 `S13`,等待创建副作用提交)
- `E10``sync_state_machine/engine/events.py::e10_bind_core()`
- `E15``sync_state_machine/engine/events.py::e15_bind_dependency()`
- `E16``sync_state_machine/engine/events.py::e16_bind_auto()`(自动绑定判定;`ZERO+create_enabled=true` 时进入 `S13`,等待创建副作用提交)
### create/update prepare
- `E20``engine/events.py::e20_create_prepare()`spawn 成功从 `S13` 提交到 `S01`;失败保持 `S13`
- `E21``engine/events.py::e21_create_prepare()`
- `E30``engine/events.py::e30_update_prepare()`
- `E20``sync_state_machine/engine/events.py::e20_create_prepare()`spawn 成功从 `S13` 提交到 `S01`;失败保持 `S13`
- `E21``sync_state_machine/engine/events.py::e21_create_prepare()`
- `E30``sync_state_machine/engine/events.py::e30_update_prepare()`
### sync execute
- `E40C_START/E40C`CREATE 执行入口与结果回写
@@ -43,10 +43,10 @@
- `E40D_START/E40D`DELETE 执行入口与结果回写
## 4. strategy 调用链(当前)
- bind 主入口:`sync_system/strategy.py::DefaultSyncStrategy.bind()` -> `strategy_ops/bind_ops.py::run_bind()`
- create 主入口:`sync_system/strategy.py::DefaultSyncStrategy.create()` -> `strategy_ops/create_ops.py::run_create()`
- update 主入口:`sync_system/strategy.py::DefaultSyncStrategy.update()` -> `strategy_ops/update_ops.py::run_update()`
- reset 主入口:`sync_system/strategy.py::BaseSyncStrategy.run_reset()` -> `strategy_ops/reset_ops.py::run_phase2_cleanup()`
- bind 主入口:`sync_state_machine/sync_system/strategy.py::DefaultSyncStrategy.bind()` -> `sync_state_machine/sync_system/strategy_ops/bind_ops.py::run_bind()`
- create 主入口:`sync_state_machine/sync_system/strategy.py::DefaultSyncStrategy.create()` -> `sync_state_machine/sync_system/strategy_ops/create_ops.py::run_create()`
- update 主入口:`sync_state_machine/sync_system/strategy.py::DefaultSyncStrategy.update()` -> `sync_state_machine/sync_system/strategy_ops/update_ops.py::run_update()`
- reset 主入口:`sync_state_machine/sync_system/strategy.py::BaseSyncStrategy.run_reset()` -> `sync_state_machine/sync_system/strategy_ops/reset_ops.py::run_phase2_cleanup()`
## 5. context 字段(以 YAML 为准)
+8 -8
View File
@@ -12,12 +12,12 @@
## 2. reset 时序
### 2.1 加载时 resetphase1 语义)
-`common/collection.py::load_from_persistence()` 执行。
-`sync_state_machine/common/collection.py::load_from_persistence()` 执行。
- 语义:仅恢复持久化状态(不在此阶段做状态归并)。
### 2.2 加载后 cleanupphase2 语义)
- pipeline 调用 `BaseSyncStrategy.run_reset()`
- 实际实现:`strategy_ops/reset_ops.py::run_phase2_cleanup()`
- 实际实现:`sync_state_machine/sync_system/strategy_ops/reset_ops.py::run_phase2_cleanup()`
- 核心事件:`E01``S16 -> S00/S15`)。
- `S16` 表示“持久化加载输入态”:本轮从持久化恢复出的节点集合(可包含上轮遗留节点,也可包含上轮已稳定节点)。
- 判定:
@@ -34,7 +34,7 @@
- 这类节点不会进入 `E01`,也不会参与 bind/create/update/sync 自动流程。
## 3. bind 流程(strategy_ops
- 入口:`strategy_ops/bind_ops.py::run_bind()`
- 入口:`sync_state_machine/sync_system/strategy_ops/bind_ops.py::run_bind()`
- 入口状态:`S00`
### 核心绑定判定
@@ -57,7 +57,7 @@
## 4. create/update 准备
### create
- 入口:`strategy_ops/create_ops.py::run_create()`
- 入口:`sync_state_machine/sync_system/strategy_ops/create_ops.py::run_create()`
- 运行时事件:`E20``E21/E22` 为配置保留分支,当前 strategy 未接入自动执行)
- 运行时入口状态:`S13`
- 说明:`E16` 负责识别“需自动创建”并将源节点置为 `S13`;业务代码执行对侧 spawn+bind 后,再通过 `E20``S13` 提交到 `S01`(成功);若 spawn 失败,`E20` 不迁移并保留在 `S13` 等待人工/重试。
@@ -66,19 +66,19 @@
- 新创建目标节点在 `S06/S10C` 阶段允许 `data_id` 为空;`CREATE SUCCESS``S11C`)必须携带非空 `result_data_id`,否则事件直接报错。
### update
- 入口:`strategy_ops/update_ops.py::run_update()`
- 入口:`sync_state_machine/sync_system/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()`
- 入口:`sync_state_machine/pipeline/full_sync_pipeline.py::normalize_create_success_to_update_entry()`
- 事件:`E41`
- 语义:`CREATE` 执行成功后,节点先落 `S11C`SUCCESS),再归并 `S11C -> S01`,作为同轮 update 起点。
## 5. 执行回写(datasource
- 入口:`datasource/datasource.py`
- 入口:`sync_state_machine/datasource/datasource.py`
- 事件:`E40C_START/E40C``E40U_START/E40U``E40D_START/E40D`
- 当前约束:delete stage 尚未接入 strategy 主流程;若运行时检测到 `S09/DELETE` 节点,DataSource 会显式抛错阻断(避免散落删除执行)。
- 执行准备入口状态:
@@ -105,5 +105,5 @@
| 隔离(人工) | `S17` | 不参与自动阶段,仅人工处理 |
## 7. 不变量保障
- 每次事件落地后,`engine/events.py::_apply_decision()` 会执行 `runtime.check_invariants()`
- 每次事件落地后,`sync_state_machine/engine/events.py::_apply_decision()` 会执行 `runtime.check_invariants()`
- 违反 invariant 直接抛错,终止当前路径。