164 lines
3.4 KiB
Markdown
164 lines
3.4 KiB
Markdown
# DataSource 接入说明
|
||
|
||
本文档说明当前 `sync_state_machine.datasource` 层的职责边界,以及新增 datasource / handler 时应如何接入。
|
||
|
||
如需看完整库化接入方式,优先参考 [docs/library_integration_guide.md](../../docs/library_integration_guide.md)。
|
||
|
||
## 1. 分层模型
|
||
|
||
当前 datasource 层分为两部分:
|
||
|
||
1. `DataSource`
|
||
- 管理 handler 注册
|
||
- 管理 collection 注入
|
||
- 负责按 `node_type` 组织 `load_all()` / `sync_all()`
|
||
- 汇总并回写 `TaskResult`
|
||
|
||
2. `Handler`
|
||
- 负责某一个 `node_type` 的具体 I/O
|
||
- 负责把原始数据转成 `SyncNode`
|
||
- 负责执行 create / update / delete / poll
|
||
|
||
设计原则:
|
||
|
||
- datasource 不承载业务策略
|
||
- strategy 不直接做底层 I/O
|
||
- 节点类型差异下沉到 handler
|
||
|
||
---
|
||
|
||
## 2. 当前可直接复用的 datasource
|
||
|
||
### 2.1 JSONL
|
||
|
||
- `JsonlDataSource`
|
||
- `BaseJsonlHandler`
|
||
|
||
适合:
|
||
|
||
- fixture
|
||
- 本地回放
|
||
- 离线调试
|
||
|
||
### 2.2 API
|
||
|
||
- `ApiDataSource`
|
||
- `ApiClient`
|
||
- `BaseApiHandler`
|
||
|
||
适合:
|
||
|
||
- HTTP 推送
|
||
- 异步任务轮询
|
||
- 远端系统对接
|
||
|
||
---
|
||
|
||
## 3. 最推荐的扩展方式:只新增 handler
|
||
|
||
多数情况下,不需要新增新的 datasource 类。
|
||
|
||
推荐做法:
|
||
|
||
1. 复用现有 `JsonlDataSource` 或 `ApiDataSource`
|
||
2. 为你的 `node_type` 新增 handler
|
||
3. 在 handler 中完成字段映射、加载、写入和轮询
|
||
4. 将 handler 注册到 `DomainRegistry`
|
||
|
||
这样可以保持:
|
||
|
||
- pipeline 不变
|
||
- datasource 生命周期不变
|
||
- 策略层不感知底层来源
|
||
|
||
---
|
||
|
||
## 4. handler 需要实现什么
|
||
|
||
### 4.1 JSONL handler
|
||
|
||
通常继承 `BaseJsonlHandler`:
|
||
|
||
```python
|
||
class DemoJsonlHandler(BaseJsonlHandler):
|
||
def __init__(self, datasource):
|
||
super().__init__(
|
||
datasource=datasource,
|
||
node_type="demo",
|
||
node_class=DemoSyncNode,
|
||
schema=DemoSchema,
|
||
)
|
||
```
|
||
|
||
### 4.2 API handler
|
||
|
||
通常继承 `BaseApiHandler`,实现:
|
||
|
||
- `load()`
|
||
- `create_all()`
|
||
- `update_all()`
|
||
- `delete_all()`
|
||
- `poll_tasks()`
|
||
|
||
并按需要补充:
|
||
|
||
- `extract_created_id()`
|
||
- `get_update_fields()`
|
||
- 依赖节点 context 读取逻辑
|
||
|
||
---
|
||
|
||
## 5. 什么时候新增 DataSource 类
|
||
|
||
只有在现有 JSONL / API 模型都不匹配时,才建议新增 `BaseDataSource` 子类。
|
||
|
||
例如:
|
||
|
||
- 数据来自数据库快照
|
||
- 数据来自 MQ / Kafka
|
||
- 数据来自特殊 RPC 或 SDK
|
||
|
||
即便新增 datasource,也建议保留同样的职责边界:
|
||
|
||
- datasource 负责调度
|
||
- handler 负责节点类型差异
|
||
|
||
---
|
||
|
||
## 6. 注册方式
|
||
|
||
接入新 `node_type` 时,最终仍通过 `DomainRegistry` 暴露给 pipeline:
|
||
|
||
```python
|
||
DomainRegistry.register(
|
||
node_type="demo",
|
||
schema=DemoSchema,
|
||
node_class=DemoSyncNode,
|
||
strategy_class=DemoStrategy,
|
||
jsonl_handler_class=DemoJsonlHandler,
|
||
api_handler_class=DemoApiHandler,
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 推荐阅读顺序
|
||
|
||
1. [docs/library_integration_guide.md](../../docs/library_integration_guide.md)
|
||
2. `sync_state_machine/datasource/handler.py`
|
||
3. `sync_state_machine/datasource/api/handler.py`
|
||
4. `sync_state_machine/datasource/jsonl/handler.py`
|
||
5. `sync_state_machine/pipeline/factory.py`
|
||
|
||
---
|
||
|
||
## 8. 结论
|
||
|
||
如果你在接入新系统,优先判断:
|
||
|
||
- 是否可以直接复用 `JsonlDataSource` / `ApiDataSource`
|
||
- 是否只需要新增 handler
|
||
- 是否需要在业务系统侧做 mapper / adapter
|
||
|
||
通常情况下,**先写 handler,而不是先写新的 datasource**。
|