300 lines
11 KiB
Markdown
300 lines
11 KiB
Markdown
# 运行配置业务说明
|
||
|
||
本文档从业务视角说明配置字段含义、对阶段行为的影响,以及推荐的覆盖方式。
|
||
|
||
## 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` 决定是否和向哪侧更新。
|
||
- 写入后 reload(Pipeline 内置)
|
||
- 对 API / 需要重新拉取权威状态的数据源,create 或 update 成功后仍会按 node_type reload。
|
||
- 对纯 JSONL -> JSONL pipeline,reload 会跳过,直接复用当前内存状态。
|
||
- 目的:避免对离线 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` 理解含义。
|