Files
ecm_sync_system/docs/runtime_config_guide.md
T
2026-04-01 11:52:57 +08:00

300 lines
11 KiB
Markdown
Raw 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.
# 运行配置业务说明
本文档从业务视角说明配置字段含义、对阶段行为的影响,以及推荐的覆盖方式。
## 0. 配置约定
当前运行配置分成两层:
1. 输入配置
- 你写在 `run_profiles/*.yaml``run_profiles/preset/*.default.yaml` 里的内容。
- 只建议写必要覆盖项,不要把默认值全部展开。
2. Resolved Full Config
- pipeline 启动时打印并写入日志的全量配置。
- 其中已经补齐 datasource 默认值、策略默认值和日志/持久化默认值。
也就是说:
- 模板应当尽量短。
- 排障时看启动日志里的 **Resolved Full Config**
### 0.1 一个最小输入示例
```yaml
local_datasource:
type: jsonl
jsonl_dir: ${PROJECT_ROOT}/filtered_datasource/datasource/filtered
remote_datasource:
type: jsonl
jsonl_dir: ${PROJECT_ROOT}/remote_datasource/datasource
persist:
db_path: ${PROJECT_ROOT}/test_results/sync_state_machine/demo.db
backend: sqlite
backend_options: {}
strategies:
project:
config:
auto_bind: true
auto_bind_fields:
- name
```
### 0.2 对应的全量 resolved 结果骨架
```yaml
node_types:
- company
- supplier
- user
- project
...
local_datasource:
type: jsonl
jsonl_dir: /abs/path/filtered_datasource/datasource/filtered
read_only: false
handler_configs: {}
remote_datasource:
type: jsonl
jsonl_dir: /abs/path/remote_datasource/datasource
read_only: false
handler_configs: {}
strategies:
- node_type: project
skip_sync: false
config:
auto_bind: true
auto_bind_fields:
- name
pre_bind_data_id: []
depend_fields:
company_id: company
local_orphan_action: create_remote
remote_orphan_action: none
update_direction: push
post_check_ignore_fields: []
compare_ignore_fields: []
domain_option: {}
persist:
backend: sqlite
db_path: /abs/path/test_results/sync_state_machine/demo.db
backend_options: {}
enable: true
wipe_on_start: false
logging:
initialize: true
file_path: null
file_dir: null
file_name_pattern: null
level: 20
suppress_node_logs: true
```
## 1. 推荐使用方式(先 default,再覆盖)
1. 先使用基线配置运行:
- `run_profiles/preset/jsonl_to_jsonl.default.yaml`
2. 若需项目定制,再复制为:
- `run_profiles/jsonl_to_jsonl.local.yaml`
3. 仅改有业务差异的字段,避免一次改太多导致排障困难。
占位符:
- `${PROJECT_ROOT}` 会在运行时替换为项目根目录绝对路径。
## 2. 顶层字段(你在改什么)
- `node_types`
- 本轮参与同步的业务类型列表。
- 顺序会影响依赖链执行时机(当前按 node_type 串行执行 bind/create/update)。
- `local_datasource` / `remote_datasource`
- 分别定义两侧数据来源与执行端。
- `strategies`
- 每个业务类型的行为策略(依赖、自动绑定、创建方向、更新方向、跳过等)。
- `persist`
- 持久化开关与数据库位置。
- `persist.backend`
- 持久化后端注册表里的名称,例如 `sqlite`
- backend 实现会自行解释 `persist` 的其余字段。
- `persist.backend_options`
- 后端私有配置,后端自己决定如何解释。
### 6. 持久化后端注册
如果你希望在 backend 初始化阶段替换持久化后端,可以先在启动代码里按名称注册,再通过配置选择,不需要改调用方。
#### 6.1 内置 SQLite
```yaml
persist:
backend: sqlite
db_path: ${PROJECT_ROOT}/test_results/sync_state_machine/demo.db
backend_options: {}
```
#### 6.2 注册自定义后端
```python
from sync_state_machine.common.persistence import register_persistence_backend
register_persistence_backend("mysql", lambda config: MySQLPersistenceBackend(config))
```
然后在配置里选择这个名字:
```yaml
persist:
backend: mysql
db_path: ${PROJECT_ROOT}/test_results/sync_state_machine/demo.db
backend_options:
url: mysql+aiomysql://user:pass@127.0.0.1/depm_sync?charset=utf8mb4
pool_size: 5
```
后端实现会收到整份 `PersistConfig`,自行决定是读取 `db_path``backend_options`,还是额外扩展别的字段。
- `logging`
- 运行日志输出位置与级别。
## 3. 数据源字段(DataSource
### 3.1 JSONL 数据源
- `type=jsonl`:使用本地 JSONL 文件作为数据源。
- `jsonl_dir`JSONL 目录路径。
- `read_only=false`:允许该侧执行 create/update 回写;若为 true,通常用于只读加载。
- `handler_configs.project.data_id_filter=[]`:项目白名单;为空时不进行项目筛选。
- `handler_configs`:按节点类型下发给各业务 handler 的扩展参数。
### 3.2 API 数据源
- `type=api`:对接 HTTP API。
- `api_base_url` / `api_uid` / `api_secret`:接口访问参数。
- `api_debug`:开启后输出更多调试信息。
- `poll_max_retries` / `poll_interval`:异步任务轮询次数与间隔。
- `handler_configs.project.data_id_filter`:建议显式配置的项目白名单;至少需要指定一个项目ID,以避免加载过多远程数据。
- `handler_configs`:业务 handler 扩展参数。
## 4. 策略字段(Strategy
每个 node_type 的 **Resolved Full Config** 都会包含以下字段,但输入配置不需要全部显式写出。
### 4.1 `update_direction`
- `push`:本地变更推送到远端。
- `pull`:远端变更拉取到本地。
- `none`:关闭 update 阶段。
### 4.2 `local_orphan_action` / `remote_orphan_action`
- `create_remote`:本地孤儿创建到远端。
- `create_local`:远端孤儿创建到本地。
- `none`:不自动创建。
- `delete_local` / `delete_remote`:当前主流程未作为默认路径,谨慎使用。
### 4.3 `auto_bind` / `auto_bind_fields` / `pre_bind_data_id`
- `auto_bind=true`:在 `S02(MISSING)` 上尝试自动匹配。
- `auto_bind=false`:不会做自动匹配,也不会走自动创建识别路径;通常会进入阻断态等待人工处理。
- `auto_bind_fields`:自动匹配使用的业务键字段。
- `pre_bind_data_id`:显式 data_id 预绑定清单(通用能力),格式为:
- `- local_data_id: "..."`
` remote_data_id: "..."`
- 规则:若两侧数据源都存在这对 data_id 对应节点,且当前无绑定记录,则直接绑定。
- 不依赖 `auto_bind/auto_bind_fields`,即使 `auto_bind=false` 也会执行。
- 不做业务键一对一匹配检查,按你给定的映射对优先执行。
### 4.4 `depend_fields`
- 定义依赖字段到依赖 node_type 的映射,例如:`company_id -> company`
- 依赖节点状态非 `NORMAL` 时,会在 bind 的依赖检查阶段进入 `DEPENDENCY_ERROR`
### 4.5 `skip_sync`
- 运行配置中已不建议使用 `skip_sync`
- 推荐使用显式组合:
- `local_orphan_action: none`
- `remote_orphan_action: none`
- `update_direction: none`
- `skip_sync=true` 的当前语义是:
- 仍会执行该 node_type 的 load / bind
- 只跳过 create / update 写入阶段
- 适合“保留绑定与依赖可见性,但临时禁止写入”的场景。
- `none/none/none` 是更推荐的输入风格,因为它表达的是“该类型不做创建、不做补本地、不做更新”。
- 这组配置不会绕过前置 load / bind / 依赖检查;它只会把该类型变成无写入策略。
### 4.6 Handler 级参数(`handler_configs`
- 建议将 handler 特有参数放在 datasource 的 `handler_configs.<node_type>` 下。
- 示例:
- `remote_datasource.handler_configs.supplier.load_mode: persisted_only`
- `persisted_only` 表示只使用已持久化数据,不主动从外部拉新数据(具体以对应 handler 实现为准)。
### 4.7 `domain_option`
- `domain_option` 用于承载 domain 自己识别的运行时扩展参数。
- 通用策略行为仍然放在 `config` 下;只有领域特例才放到 `domain_option`
示例 1`project` 先从远端拉回两个特殊投产日期字段,再执行默认 push
```yaml
project:
domain_option:
pull_group_plan_production_date: true
config:
update_direction: push
```
示例 2`project_detail_data` 用单个开关启用固定业务规则,把集团保供/爬坡/挑战产能计划按 pull 处理
```yaml
project_detail_data:
domain_option:
pull_group_production_plans: true
config:
update_direction: push
```
含义:
- `project.domain_option.pull_group_plan_production_date=true` 时,`ic_plan_first_production_date``ic_plan_full_production_date` 会先 remote -> local,再执行剩余字段的常规更新。
- `project_detail_data.domain_option.pull_group_production_plans=true` 时,固定的 `ensure_production``climb_production``challenge_production` 会先 remote -> local;其余 key 继续沿用 `config.update_direction`
## 5. 阶段行为与配置关系
- bind 阶段
- `depend_fields` 决定是否做依赖校验。
- `pre_bind_data_id` 先按显式 local/remote data_id 映射做预绑定。
- `auto_bind/auto_bind_fields` 决定是否继续进行业务键自动绑定。
- create 阶段
- `local_orphan_action` / `remote_orphan_action` 决定孤儿是否创建。
- update 阶段
- `update_direction` 决定是否和向哪侧更新。
- 写入后 reloadPipeline 内置)
- 对 API / 需要重新拉取权威状态的数据源,create 或 update 成功后仍会按 node_type reload。
- 对纯 JSONL -> JSONL pipelinereload 会跳过,直接复用当前内存状态。
- 目的:避免对离线 JSONL 数据做无意义重复扫描,同时保留 API 数据源的权威状态刷新。
- 同步后一致性检查(Pipeline 内置)
- 每个 node_type 在本轮同步后会基于绑定对执行数据一致性校验(比较时忽略 `id/_id` 字段)。
- 若发现差异,会在日志中打印差异样本,并在汇总表新增 `Consistent` 列展示 `Y` / `N(差异数)`
- 全局跳过
- `local_orphan_action=none` + `remote_orphan_action=none` + `update_direction=none`
可将该类型收敛为“只做 load/bind,不做 create/update 写入”的只读同步策略。
## 6. 覆盖配置建议
- 先在 default 跑通一轮,再做 local 覆盖。
- 每次只改一类问题相关字段(例如只改 `project` 的依赖与自动绑定)。
- 覆盖后优先看 `sync_log` 是否出现预期状态迁移。
## 7. 持久化与日志字段
### `persist`
- `enable`:是否开启持久化。
- `db_path`SQLite 路径。
- `wipe_on_start`:启动是否清理历史持久化。
### `logging`
- `file_dir`:日志目录。
- `file_name_pattern`:文件命名模板。
- `level`:日志级别。
排障建议:运行失败时优先看日志中的 `状态机流转``reason=`,再对照 `docs/state_machine.md``docs/node_state_definition.md` 理解含义。