Skip to content

Latest commit

 

History

History
195 lines (160 loc) · 8.68 KB

File metadata and controls

195 lines (160 loc) · 8.68 KB

docs/log_flow.md - 📊 PowerBarcoder 訊息流設計架構

1. 整體架構概述

PowerBarcoder 採用前後端分離的設計,使用 SSE + HTTP 架構實現即時日誌顯示與處理程序控制:

sequenceDiagram
   autonumber
   participant User as 使用者
   participant FE as 前端 (Vue.js)
   participant IndexedDB as 瀏覽器 IndexedDB
   participant BE as 後端 (Flask app.py)
   participant BSM as 批次狀態管理器 (batch_status_manager.py)
   participant Proc as PowerBarcoder 主流程
   participant File as 批次狀態文件 (JSON)
%% 提交處理請求
   User ->> FE: 填寫並提交表單
   FE ->> BE: POST /run-procedure
   BE ->> BE: 生成 batch_id、轉換為 YAML、建立目錄、啟動子流程
   BE ->> Proc: 執行處理流程
   BE -->> FE: 回傳 batch_id (JSON)
%% SSE 日誌串流建立
   FE ->> BE: 建立 SSE 連線 (/stream/<batch_id>)
   BE ->> Proc: 配置 stdout 重導、不緩衝讀取
   loop 每行日誌
      Proc ->> BE: 輸出一行日誌
      BE -->> FE: SSE 傳送日誌訊息
      FE ->> IndexedDB: 將日誌緩存到本機存儲
   end
   Proc -->> BE: 處理結束
   BE -->> FE: 結束 SSE 串流
%% PowerBarcoder 主流程批次狀態更新
   loop 處理步驟間
      Proc ->> BSM: 更新當前執行步驟
      BSM ->> File: 寫入狀態到批次目錄
   end

%% 頁面重載後恢復連接
   User ->> FE: 重新整理頁面
   FE ->> IndexedDB: 讀取保存的批次狀態和日誌
   FE ->> BE: 檢查批次狀態 (/batch-status/<batch_id>)
   alt 批次仍在運行
      FE ->> BE: 重建 SSE 連線
   else 批次已結束
      FE ->> IndexedDB: 載入所有保存的日誌
      FE -->> User: 顯示完整日誌與結果
   end
Loading

2. 核心功能設計

本文件聚焦「日誌(Log) + 狀態(Status) + 進度(Progress)」三層資料在前後端間的一致性。相較於舊版只輸出未分類純文字,本版定義:

類別 目的 現狀 (Current) 備註
Log 行 人類可讀過程訊息 純文字行 (SSE data) IndexedDB 全量保存
Progress 狀態 UI 步驟 / 百分比 透過 batch-status Poll / 偶爾寫檔 用於 state machine 對齊 frontend.md
Metrics 效能與統計 未輸出 避免日誌肥大
Error 事件 可回復 / 致命訊號 嵌在文字行中 UI 可分類呈現

Glossary 用語:status, current_step, steps_completed, log_source, log_level 參見 glossary.md

2.1 批次處理與狀態管理

  1. 批次狀態類型 (與 frontend.md / qc.md 對齊):

    • running:正在運行中
    • completed:已正常完成(全部 locus 全部步驟成功)
    • failed:執行失敗(任一致命錯誤,詳見 error taxonomy)
  2. 處理步驟類型 (step taxonomy):細化以支持更精準 UI 進度條與失敗定位。現行必定寫入 current_step 的主階段,其下子步驟(非全部目前實作):

主階段 子步驟 說明 錯誤影響 UI 映射
env_check tool_version_check 檢查外部依賴 (BLAST, R, MAFFT) 致命 Validation
dir_setup prepare_output_dirs 建立輸出/暫存/日誌目錄 致命 Initializing
demultiplex cutadapt_run / fastp_trim 條碼拆分 + 品質剪裁 致命 Demultiplex
denoise dada2_error_model / dada2_infer_asv / abundance_filter R DADA2 流程 致命 Denoise
merge blast_search / blast_parse / pairing / overlap_resolve / consensus_export BLAST + 配對 + 重疊裁剪 子步驟失敗可標記 locus 局部失敗 Merge
qc locus_qc / overall_qc 單 locus 與全域 QC locus_qc 失敗不一定終止全局 QC
llm_analysis rule_judge / llm_call / parse / fallback LLM 仲裁 (可選) 失敗 fallback 至 rule_judge LLM
finalize pack_results / write_summary 打包與總結 致命 Finalize

現行仍使用較粗粒度步驟寫入。

  1. 狀態檔案結構:現行僅包含單一 current_step
{
  "batch_id": "202504250135",
  "status": "running",
  "current_step": "denoise",
  "start_time": "2025-04-25T01:35:00.000Z",
  "update_time": "2025-04-25T01:45:30.000Z",
  "end_time": null,
  "steps_completed": ["env_check", "dir_setup", "demultiplex"]
}

2.2 日誌流處理機制

  1. SSE 串流實現要點

    • 基於 Flask stream_with_context 實現串流響應
    • 子進程 stdout -> 非阻塞讀取 -> queue -> 逐行 yield
    • 無緩衝輸出策略確保<200ms latency
    • 現狀格式:data: <raw_line>\n\n(僅文字)
    • 需保留 id: 欄位以支持重連斷點
    • 移除 ANSI 序列(過濾正則)避免 UI 碎裂
    • 末尾顯式 [END] 行標記
  2. 連接管理與維護策略

    • 目前:瀏覽器 EventSource 內建退避重連 (browser-managed backoff)
    • 若多次重連失敗 → 前端改用 /batch-status 輸出 fallback UI(見 frontend.md 連線策略)
    • 斷線期間遺失的行(若將來使用 SSE id)可經由 /logs/<batch_id>?since=<id> 補齊
    • [END] 行觸發:關閉 EventSource、寫入完成狀態、允許下載按鈕啟用
  3. 資源管理與清理

    • 閒置閾值(預設 30 分鐘)後端定期掃描 (cron/thread)
    • 清理條件:status in {completed, failed} 且最後訪問 > threshold
    • 清理操作:關閉文件 handle、移除暫存檔、保留最終結果 + 狀態檔 + 匯總日誌
    • 寫入統計摘要(log bytes, line count)供 metrics 用
  4. 前端日誌持久化(與 frontend.md 對齊):

    • Bulk buffer (e.g. 50 行或 2 秒) 再批量寫入 IndexedDB
    • 匯出:合併行 → UTF-8 文本下載
    • 重新整理:先載入 IndexedDB → 再建立 SSE → 去重(先採簡單比對末尾)
    • 錯誤行標記:UI 高亮 + 快速跳轉

2.3 批次狀態管理

  1. 批次狀態追蹤機制

    • 單例管理器(thread-safe 寫入鎖)
    • 每個批次獨立 status.json(實際命名以程式為準)
    • 步驟轉換:附 update_time
    • 允許在失敗後仍查詢最後 error_code & message
  2. 狀態檢查與追蹤

    • /batch-status/<batch_id> 回傳最小必要集:status, current_step, update_time
    • 用於前端 fallback poll(SSE 暫時不可用時)
    • 失敗案例:附上 error_code (分類) 與 hint(改善建議)

3. API 端點與數據交換

3.1 主要 API 端點

端點 方法 說明
/run-procedure POST 提交處理請求,啟動批次處理
/stream/<batch_id> GET 建立 SSE 連接,串流處理日誌(目前僅 log 行)
/batch-status/<batch_id> GET 獲取批次狀態資訊
/download/<room_name> GET 下載批次處理結果壓縮包(後端參數名為 room_name,通常對應於 batch_id 所建立的結果資料夾)

3.2 SSE 使用要點

  1. 前端設計思路

    • EventSource 建立後:onmessage → append buffer → debounce 寫入 IndexedDB
    • onerror:暫停一段退避時間 → 檢查 /batch-status → 決定是否重建連線
    • [END] 行或 status=completed/failed → 關閉連線並刷新最終狀態
  2. 後端設計思路

    • Header: Cache-Control: no-cache, Content-Type: text/event-stream
    • Flush 每行避免代理緩衝
    • 捕捉子進程錯誤:在最後輸出 [ERROR:<code>:<summary>](暫存格式)
    • 可加入心跳 :keepalive 行避免閒置斷線

4. 技術選擇依據

  1. 選用 SSE 而非 WebSocket 的理由

    • PowerBarcoder 主要需求是單向通訊(服務器→客戶端日誌流)
    • SSE 基於標準 HTTP,更易於通過代理和防火牆
    • 內建自動重連機制,實現更簡單
    • 資源消耗更低,更適合長時間批處理任務
  2. 前端狀態持久化選擇

    • IndexedDB 作為前端日誌儲存方案,支援大量結構化數據
    • 使用緩衝區批量寫入,降低 I/O 操作頻率
    • 結合時間閾值和數量閾值的混合策略,確保數據及時保存
    • 提供頁面重載後的日誌恢復機制,避免日誌丟失
  3. 狀態文件存儲設計

    • 將狀態文件與結果存放在同一目錄,便於管理
    • 每個批次獨立目錄,清理和備份更方便
    • JSON 格式便於監控和調試
    • 使用時間戳記錄關鍵狀態變更
  4. 批次 ID 生成策略

    • 基於時間戳的批次 ID,確保唯一性並提供時序資訊
    • 可選添加隨機字符串處理罕見的時間戳衝突
    • 批次 ID 作為目錄名稱與檔案標識符的統一基礎
  5. 日誌記錄優化

    • 現狀:部分行帶時間戳
    • 分級建議:INFO, WARN, ERROR, DEBUG (debug 可選啟用)
    • source 建議:pipeline, r_dada2, blast, qc, llm, system
    • 支援過濾顯示與快速跳轉到 ERROR 區段