45 lines
3.6 KiB
Markdown
45 lines
3.6 KiB
Markdown
# 外围工单主动同步
|
|
|
|
工单的创建、编辑、现场反馈和删除改为由来源事件触发同步。浏览器继续使用已有工作台 SSE,不需要新增连接或定时工单轮询。
|
|
|
|
```text
|
|
外围工单写入
|
|
→ 同一 PostgreSQL 事务保存源记录、历史版本和变更事件
|
|
→ COMMIT 后 NOTIFY
|
|
→ Server 工作台 SSE 唤醒外围同步器
|
|
→ 同步器通过授权 API 更新任务投影
|
|
→ task/action/notification 事件推送给浏览器
|
|
```
|
|
|
|
## 数据库范围
|
|
|
|
本次仅启用 `tjwater_v2`。没有新增表、列或迁移;复用 `workbench.domain_event_log` 的 `workbench.work_order.changed` topic。源事件的聚合类型为 `peripheral_work_order`,元数据只包含 `source=peripheral_sample`、工单 ID 和 `created|updated|deleted`,不包含工单正文。事务失败时,源记录、历史、事件及通知一起回滚;同一请求的幂等重放不再产生事件。
|
|
|
|
外围服务只写源记录及源变更事实,不直接改业务任务。任务投影、调查创建和通知仍通过 Server 状态机和现有授权 API 处理。其他数据库不写入该源事件;扩展前遵循 [数据库变更门禁](workbench-database-rollout.md)。事件表缺失或无写权限时,`tjwater_v2` 的工单写入返回存储错误,不会假装成功。
|
|
|
|
## 同步器
|
|
|
|
从 Server 仓库运行已有命令:
|
|
|
|
```bash
|
|
conda run -n server python scripts/sync_peripheral_work_orders.py
|
|
conda run -n server python scripts/sync_peripheral_work_orders.py --once
|
|
```
|
|
|
|
继续复用 `OPERATIONAL_WORKER_*` OAuth 工作身份及 `OPERATIONAL_ACTION_PERIPHERAL_URL`,不需要新账号或密钥。启动和游标过期时先读取事件游标,再进行全量对账;扫描期间的事件从该游标继续补读。相同源版本仍由原幂等键去重。同步器只被 `peripheral_work_order` 源事件唤醒,不被自己写出的任务投影事件再次唤醒。
|
|
|
|
正常状态收到源事件即扫描;无事件时默认每 300 秒对账一次,处理漏通知、断线、旧批量脚本直接写库及重启。可用 `--reconcile-seconds` 调整这一兜底周期(最小 1 秒),不再复用工况 worker 的 30 秒租约检查周期。同步失败按 5、10、20、40、60 秒退避重试;事件连接断开每 5 秒重试,保留最后游标。扫描开始前清除唤醒标记,扫描期间新到达的事件会触发下一轮,失败后的重试也不依赖新消息。
|
|
|
|
浏览器收到源事件时不会提前刷新业务快照,而是等待任务投影事件后读取对应任务。工况手动刷新仍只读 Server 权威快照。工单事件不等于 Header 通知;只有需要处理的业务待办或告警才进入通知列表。
|
|
|
|
## 验证与启用
|
|
|
|
```bash
|
|
conda run -n server python -m pytest tests/unit/test_peripheral_push_sync.py tests/unit/test_peripheral_work_order_events.py tests/unit/test_peripheral_task_sync.py -q
|
|
PERIPHERAL_SAMPLE_LIVE_TEST=1 conda run -n server python -m pytest tests/integration/test_peripheral_work_order_events.py -q
|
|
```
|
|
|
|
数据库测试强制限定 `tjwater_v2`,使用随机项目键和回滚事务,不保留测试工单或事件。覆盖创建、修改、反馈、删除、幂等重放及回滚无事件。HTTP 隔离测试覆盖源事件即时投影、游标重置、断线续传、失败重试和监听取消。
|
|
|
|
上线时更新外围服务、Server 同步器及前端,再按既有发布流程重启对应进程。提交代码不会自动重启现有服务;旧同步器进程仍按旧的 30 秒周期运行。回退应用代码不涉及数据结构回滚,已有事件仍可正常补读;回退到旧同步器后恢复周期对账。
|