Fundamental_Analysis/docs/tasks/completed/20251130_frontend_realtime_logs_flow.md
Lv, Qi e9e4d0c1b3 chore: massive update covering recent refactoring and bug fixes
- fix: infinite message loop in workflow orchestrator
- feat: restore realtime LLM streaming from report generator to frontend
- refactor: major update to provider services (generic workers, workflow adapters)
- refactor: common contracts and message definitions updated
- feat: enhanced logging and observability in orchestrator
- docs: update project management tasks and status
- chore: dependency updates and config adjustments
2025-11-30 19:17:02 +08:00

4.0 KiB
Raw Blame History

任务Realtime Logs 数据流优化 (缓冲与回放) [已完成]

目标

解决前端 Realtime Logs 面板在页面刷新、重新连接或初始加载延迟时丢失日志的问题。 目标是确保 "First-hand" 服务端日志能够可靠地流向前端,不依赖 NATS 的临时性。

实施方案

1. 后端:增强 SyncStateCommand (Orchestrator)

我们需要修改 handle_sync_state 逻辑,使其在发送状态快照的同时,也能读取当前的临时日志文件,并将历史日志作为事件发送给前端。

  • 修改 workflow.rs -> handle_sync_state:
    • 调用 log_manager.read_current_logs(req_id) (需要新增此方法,非破坏性读取)。
    • 读取到的日志内容可能是巨大的字符串。为了不阻塞 NATS 消息,可以分块发送,或者作为 WorkflowStateSnapshot 的一部分发送(如果大小允许)。
    • 方案选择: 发送一个新的事件类型 WorkflowLogHistory 或者复用 TaskLog(批量发送)。
    • 鉴于前端 handleEvent 处理 TaskLog 是追加式的,我们可以循环发送 TaskLog 事件。
    • 更优方案: 在 WorkflowStateSnapshot 结构体中增加 logs: Vec<String> 字段。这样前端在恢复快照时一次性填入。

2. 定义数据结构变更

  • common-contracts/src/messages.rs:
    • 修改 WorkflowStateSnapshot,增加 logs: Vec<String>

3. 完善 LogBufferManager

  • logging.rs:
    • 新增 read_current_logs(&self, request_id: &str) -> Result<Vec<String>>
    • 读取文件,按行分割,返回 Vec<String>

4. 前端适配

  • useWorkflowStore.ts:
    • handleEvent -> WorkflowStateSnapshot 分支中,处理 event.payload.logs
    • 将这些日志合并到 state.logs (Global Logs) 或者解析后分发到 state.tasks (如果日志格式包含 Task ID)。
    • 目前日志格式为 [ISO Time] [Level] Message,不一定包含 Task ID所以主要作为 Global Logs 展示。

5. 流程梳理

  1. 前端启动/刷新:
    • 调用 SSE /events/{id}
    • API Gateway 收到连接,订阅 NATS并发送 SyncStateCommand 给 Orchestrator。
  2. Orchestrator:
    • 收到 SyncStateCommand
    • 生成 DAG 快照。
    • 读取 temp_logs/{id}.log
    • 构建 WorkflowStateSnapshot (包含 logs)。
    • 发布到 NATS。
  3. 前端接收:
    • 收到 Snapshot。
    • 恢复 DAG 状态。
    • 恢复 Logs 面板内容。
  4. 后续实时日志:
    • Orchestrator 继续运行Tracing Layer 写入文件。
    • 关键点: 我们之前删除了 publish_log。现在需要恢复实时推送能力,但不是手动调用。
    • 方案: FileRequestLogLayer 除了写文件,还应该有一个机制将日志推送到 NATS 吗?
    • 回答: 是的。之前的重构把推送删了,导致前端收不到实时更新了。
    • 修正: FileRequestLogLayer 应该同时负责:
      1. 写文件 (持久化缓冲)。
      2. 推送到 NATS (实时展示)。
    • 技术难点: Layer 是同步的NATS 是异步的。
    • 解决: 使用 tokio::sync::broadcastmpsc 通道。Layer 将日志发送到通道,有一个后台 Task 负责接收通道消息并推送到 NATS。

修正后的后端任务列表

  1. 恢复实时推送通道:
    • AppState 中增加一个 log_broadcast_tx (sender)。
    • FileRequestLogLayer 持有这个 sender。
    • main.rs 启动一个后台任务,监听 receiver将日志封装为 WorkflowEvent::TaskLog 并推送到 NATS。
  2. 实现历史回放 (Snapshot):
    • 修改 WorkflowStateSnapshot 增加 logs 字段。
    • LogBufferManager 增加读取方法。
    • handle_sync_state 填充 logs。

前端任务列表

  1. 更新 WorkflowStateSnapshot 类型定义。
  2. 在 Store 中处理 Snapshot 携带的日志。

这个方案兼顾了实时性和可靠性(断线重连)。