chore: #7 kline:tick 微回补文档同步 + ws.ts 显式判断
- ws.ts: !msg.kline.final → msg.kline.final === false 更清晰 - websocket-realtime.md: 事件表/启动流程/角色表补上 kline:tick,#7 标记已修复 - tech-debt.md: #10 kline:tick 标记已完成
This commit is contained in:
@@ -87,7 +87,7 @@ export class BinanceWsClient extends BaseWsClient {
|
||||
|
||||
private handleKline(msg: WsMessageKlineFormatted): void {
|
||||
const kline = this.toKline(msg);
|
||||
if (!msg.kline.final) {
|
||||
if (msg.kline.final === false) {
|
||||
bus.emit("kline:tick", kline);
|
||||
return;
|
||||
}
|
||||
|
||||
+4
-4
@@ -131,10 +131,10 @@
|
||||
- 问题:同时承担 REST client registry(7-30 行)和 WS 订阅管理(74-121 行),两类逻辑耦合
|
||||
- 修复:拆分为 `rest-registry.ts`(REST client 注册 + fetchKlines)+ `ws-manager.ts`(WS 实例池 + watchKline/watchKlines/unWatchKline),`index.ts` 降级为纯 re-export hub,对外 API 不变
|
||||
|
||||
- [ ] **10. `kline:tick` 微回补未实现**(已知问题 #7)
|
||||
- 位置:`data/exchanges/binance/ws.ts:62-63` + `data/run/start.ts`
|
||||
- 问题:WS 订阅后的衔接窗口期(回补完成 → subscribe 之间若跨分钟边界)可能导致最多 1 分钟数据缺口。文档方案已明确,待实现
|
||||
- 建议:`ws.ts` 中 `final === false` 时 emit `kline:tick`,`start.ts` 首次 tick 触发微回补
|
||||
- [x] **10. `kline:tick` 微回补**(已知问题 #7)
|
||||
- 位置:`data/exchanges/binance/ws.ts` + `data/run/start.ts` + `data/utils/bus.ts`
|
||||
- 问题:WS 订阅后的衔接窗口期(回补完成 → subscribe 之间若跨分钟边界)可能导致最多 1 分钟数据缺口
|
||||
- 修复:`ws.ts` 中 `final === false` 时 emit `kline:tick`,`start.ts` 首次 tick 触发 `backfillKline` 微回补,`tickedSymbols` 去重仅执行一次。commit `6374159`
|
||||
|
||||
- [x] **11. `fetchMarkets()` 返回空数组**
|
||||
- 位置:`data/exchanges/binance/rest.ts:133,194`
|
||||
|
||||
@@ -78,6 +78,7 @@ start.ts 启动
|
||||
│ ├─ pair:ready → watchKline({exchange, type, symbol})
|
||||
│ ├─ pair:failed → 记日志
|
||||
│ ├─ backfill:complete → 记日志
|
||||
│ ├─ kline:tick → 首次 tick 触发 backfillKline 微回补(#7)
|
||||
│ ├─ kline:update → upsertOrUpdateKlines → updatePairWsTime → emit("kline:saved")
|
||||
│ └─ kline:saved → checkAndRefresh → emit("aggregate:refreshed")
|
||||
│
|
||||
@@ -244,6 +245,7 @@ run/start.ts 启动
|
||||
│ ├─ pair:ready → watchKline({exchange, type, symbol})
|
||||
│ ├─ pair:failed → 记日志 + 计数
|
||||
│ ├─ backfill:complete → 记日志
|
||||
│ ├─ kline:tick → 首次 tick 触发 backfillKline 微回补(#7)
|
||||
│ ├─ kline:update → upsertOrUpdateKlines → updatePairWsTime → emit("kline:saved")
|
||||
│ └─ kline:saved → checkAndRefresh → emit("aggregate:refreshed")
|
||||
│
|
||||
@@ -279,7 +281,7 @@ run/start.ts 启动
|
||||
|
||||
| 模块 | 角色 | 监听 bus 事件 |
|
||||
|------|------|------|
|
||||
| `run/start.ts` | 编排入口:注册所有监听、桥接 service、调起回补 | `pair:ready` `pair:failed` `backfill:complete` `kline:update` `kline:saved` `ws:connected` `ws:disconnected` `ws:stale` |
|
||||
| `run/start.ts` | 编排入口:注册所有监听、桥接 service、调起回补 | `pair:ready` `pair:failed` `backfill:complete` `kline:tick` `kline:update` `kline:saved` `ws:connected` `ws:disconnected` `ws:stale` |
|
||||
| `exchanges/binance/ws.ts` | WS 客户端:订阅管理 + 标准化 + emit(不监听 bus) | — |
|
||||
| `service/kline.ts` | 数据写入:导出 `upsertOrUpdateKlines`(被动调用) | — |
|
||||
| `service/pair.ts` | 时间标记:导出 `updatePairWsTime`(被动调用) | — |
|
||||
@@ -386,7 +388,7 @@ start.ts 在正常运行时持续推进 last_backfill_time,exchange.ts 再次
|
||||
| `pair:failed` | 回补模块 | start.ts | `{symbol, type, exchange, error}` |
|
||||
| `backfill:complete` | 回补模块 | start.ts | `{status: 'done'\|'error'}` |
|
||||
| `kline:update` | exchanges/ws.ts | start.ts | `Kline`(已闭合) |
|
||||
| `kline:tick` | exchanges/ws.ts | start.ts | `Kline`(未闭合,触发衔接微回补 #7)**⏸️ 暂缓:事件未定义,ws.ts 不 emit** |
|
||||
| `kline:tick` | exchanges/ws.ts | start.ts | `Kline`(未闭合,触发衔接微回补 #7)|
|
||||
| `kline:saved` | start.ts | start.ts | `Kline` |
|
||||
| `aggregate:refreshed` | start.ts | 策略引擎 | `Kline` |
|
||||
| `ws:connected` | exchanges/ws.ts | start.ts | — |
|
||||
@@ -488,4 +490,4 @@ data/
|
||||
| 4 | WS 端 `takerBuyBaseVol` / `takerBuyQuoteVol` 硬编码为 `"0"` | `ws.ts:76-77` 两个字段写死为 `"0"`。已改为 `msg.kline.volumeActive` / `msg.kline.quoteVolumeActive` | ✅ 已修复 |
|
||||
| 5 | 回补失败后 `break` 静默丢弃剩余 pair | `backfill.ts:84` 任一 pair 失败 `break`。**设计决策**:失败属不可恢复错误(SDK 僵死不响应 timeout),退出进程由外部重启,与第六章策略一致。**修复**:`run/start.ts` 中 `backfill:complete` 监听到 `status === 'error'` 时 `process.exit(1)` | ✅ 已修复 |
|
||||
| 6 | 未来 `watchKline` 异步化的 race condition 隐患 | `start.ts` 中 `watchKline` 为同步调用,当前无问题。异步化后回补→WS 订阅的时间差可能导致数据缺口。**已明确**:此问题实质是衔接窗口问题,由 #7 的首次微回补方案覆盖 | ✅ → #7 |
|
||||
| 7 | 回补→WS 衔接可能存在数据缺口 | 回补与 `subscribe` 之间若跨过分钟边界,该分钟内已闭合的 K 线不会被 WS 推送(WS 只推当前运行中的 K 线)。**决策**:数据完整性优先。每个交易对首次收到 `kline:tick` 时,即刻强制执行一次微回补(REST `fetchKlines` 从 `last_backfill_time` 到该 tick 的 `openTime`),无需等 1m K 线闭合。`kline:tick` 在 WS 订阅后数秒内即可到达,将衔接窗口从最长 1 分钟压缩到秒级。仅触发一次,后续 tick 忽略 | ⏸️ |
|
||||
| 7 | 回补→WS 衔接可能存在数据缺口 | 回补与 `subscribe` 之间若跨过分钟边界,该分钟内已闭合的 K 线不会被 WS 推送(WS 只推当前运行中的 K 线)。**决策**:数据完整性优先。每个交易对首次收到 `kline:tick` 时,即刻强制执行一次微回补(调用 `backfillKline` 从 `last_backfill_time` 补齐至上一闭合分钟),无需等 1m K 线闭合。`kline:tick` 在 WS 订阅后数秒内即可到达,将衔接窗口从最长 1 分钟压缩到秒级。仅触发一次,后续 tick 忽略。实现于 commit `6374159` | ✅ 已修复 |
|
||||
|
||||
Reference in New Issue
Block a user