# Processor 產出機制檢討 ## 三層機制定義 ### 1. 中斷接續(Interruption Resume) Process 被殺掉後,重啟時能接續進度。 **現狀**: 大部分 processor 有 `.tmp` → `.partial` 保護,但重跑時從頭開始。 ### 2. 補充機制(Supplement) 完成度不足時,只補沒做完的部分,不重跑整個。 **現狀**: 全部從頭跑,無補充。 ### 3. 糾錯機制(Error Correction) 輸出檔損毀時能自動偵測並修復。 **現狀**: file-existence check 只檢查檔案存在,不檢查內容是否有效。 --- ## Processor 逐一檢討 ### ASR | 面向 | 現狀 | 問題 | |------|------|------| | 中斷接續 | ✅ `.tmp` → `.partial`(executor) | ✅ OK | | 補充機制 | ❌ 每次從頭跑 | 若跑到 50% 被殺,下次從 0% 開始 | | 糾錯機制 | ❌ 不驗證內容 | file-existence check 看到 `.json` 存在就跳過,不管內容 | | Pipe | ✅ executor.run() | ✅ | | Timeout | ✅ 已移除(None) | ✅ | **改善方案**: - 補充:ASR 重跑時掃描 existing `.json` 或 `.partial`,找出最後 segment 的 `end_time`,傳入 `--resume-from` 給 Python script - 糾錯:file-existence check 對 `.json` 做 `serde_json::from_str` 驗證,無效 → 視為不存在 ### ASRX | 面向 | 現狀 | 問題 | |------|------|------| | 中斷接續 | ❌ **不用 executor**,直接寫 `.json` | 被殺掉時留下壞檔 | | 補充機制 | ❌ 同 ASR | 依賴 ASR,ASR 不完整 ASRX 也不能跑 | | 糾錯機制 | ❌ 不驗證內容 | 同上 | | Pipe | ❌ **raw Command**,沒有 `.tmp` 保護 | 緊急 | | Timeout | ⚠️ 7200s hardcode | 應改為 None(同 ASR) | **改善方案**: - **最優先**: 改為使用 `executor.run()`,獲得 `.tmp` 保護 - 其他同 ASR ### YOLO | 面向 | 現狀 | 問題 | |------|------|------| | 中斷接續 | ✅ executor `.tmp` | ✅ | | 補充機制 | ❌ 從頭跑 | 若跑到 frame 100,000 被殺,下次從 frame 0 | | 糾錯機制 | ❌ 不驗證內容 | yolo.json 之前就是壞的但 file check 跳過 | **改善方案**: - 補充:掃描 `.partial` 的最後 frame,傳入 `--resume-frame` 給 Python script - 糾錯:file-existence check 對 `.json` 做 JSON parse 驗證 ### FACE / POSE / OCR | 面向 | 現狀 | 問題 | |------|------|------| | 中斷接續 | ✅ executor `.tmp` | ✅ | | 補充機制 | ❌ 從頭跑 | 同 YOLO | | 糾錯機制 | ❌ 不驗證內容 | 同 YOLO | **改善方案**: 同 YOLO ### CUT | 面向 | 現狀 | 問題 | |------|------|------| | 中斷接續 | ✅ executor `.tmp` | ✅ | | 補充機制 | ✅ register 階段已完成,直接載入 | ✅ | | 糾錯機制 | ❌ 不驗證內容 | 同 YOLO | **改善方案**: 糾錯即可 ### SCENE | 面向 | 現狀 | 問題 | |------|------|------| | 中斷接續 | ✅ **最完整**:檢查 `.err`/`.json`/`.tmp` 三種狀態 | ✅ | | 補充機制 | ❌ 從頭跑 | ✅(scene 很快) | | 糾錯機制 | ⚠️ 有檢查 `.err` | ✅ | ### VISUAL_CHUNK | 面向 | 現狀 | 問題 | |------|------|------| | 中斷接續 | ✅ executor `.tmp` | ✅ | | 補充機制 | ❌ | ❌ | | 糾錯機制 | ❌ **錯誤被吞掉**(回傳空結果) | 應回報 error 而非靜默失敗 | **改善方案**: 不要吞錯誤,讓 error 往上傳 ### STORY | 面向 | 現狀 | 問題 | |------|------|------| | 中斷接續 | ✅ executor `.tmp` | ✅ | | 補充機制 | ❌ | ❌ | | 糾錯機制 | ❌ | ❌ | --- ## 優先級 ### P0 — 立即修復 1. **ASRX 改用 executor.run()** - 檔案:`src/core/processor/asrx.rs` - 獲得 `.tmp` 保護、SIGKILL process group、`.partial` 保留 - 移除 hardcode timeout ### P1 — 糾錯機制 2. **File-existence check 加入 JSON 驗證** - 檔案:`src/worker/job_worker.rs` - 在 `output_path.exists()` 之後,對 `.json` 做 `serde_json::from_str::` - 若 parse 失敗 → 不 skip,當作檔案不存在繼續跑 - 若 parse 成功但內容空(無 segments/frames)→ 當不完整 ### P2 — 補充機制 3. **ASR resume-from 補充** - 檔案:`src/core/processor/asr.rs` + `scripts/asr_processor.py` - Rust 端發現 `.partial` 存在,讀取最後 segment 的 end_time - 傳入 `--resume-from {time}` 給 Python script - Python script 跳過 `--resume-from` 之前的音訊 4. **YOLO/Face/Pose resume-frame 補充** - 檔案:各 processor.rs + 對應 Python script - 掃描 `.partial` 中的最後 frame_number - 傳入 `--resume-frame {frame}` 給 Python script ### P3 — 其他 5. **VisualChunk 不吞錯誤** 6. **Executor SIGTERM → SIGKILL 兩段式關閉**