MySQL TaskStore 節點 / 命令 / 詳細 log table 邊界分析
1. 文件目的
本文件整理 MySQL TaskStore 第一版 PoC 完成後,是否要把節點歷程、設備命令與詳細 log table 納入第二階段下一批。
本文件只做邊界分析與實作順序建議,不直接修改資料表、C# model、public method 簽章、ConsoleHost 啟動方式,也不執行真實 DB 寫入或 DDL。
2. 目前已完成狀態
| 項目 | 狀態 | 說明 |
|---|---|---|
task_executions | 已完成第一版 PoC | 已完成 Save upsert、FindById、ListRecent 與真實 DB manual-only 驗證。 |
TaskExecutionRecord.NodeRecords | 已存在 | 可記錄節點摘要,包含 NodeId、NodeName、DeviceId、CommandName、Status、RetryCount、TimeTakenMs、DataSummary、MetadataSummary、NextNodeId、TransitionSummary。 |
WorkflowNodeExecutionSnapshot | 已存在 | 比 TaskNodeExecutionRecord 更接近 Workflow 完成瞬間,包含 AdapterTimeTakenMs、RawRequestSummary、RawResponseSummary。 |
LogEntry | 已存在 | 已承接 TaskId、NodeId、DeviceId、CommandName、Status、RetryCount、TimeTakenMs、AdapterTimeTakenMs、DataSummary、RawRequestSummary、RawResponseSummary、MetadataSummary、ErrorCode、Message。 |
| MySQL Schema Automation | 已完成第一輪 | 可用 C# schema class 維護欄位、索引、描述,並以 dry run 產生 SQL preview。 |
3. 邊界結論
建議第二階段下一批不要一次把節點、命令與詳細 log 全部實作,而是拆成三個層級:
| 層級 | 建議狀態 | 原因 |
|---|---|---|
node_executions | 建議優先納入下一批 | 目前 TaskExecutionRecord.NodeRecords 已有足夠資料,可不改 public contract 先保存節點摘要。 |
command_executions | 建議先做實作前確認 | 目前最完整的 RawRequest / RawResponse 來源在 WorkflowNodeExecutionSnapshot 與 LogEntry,不是 TaskNodeExecutionRecord;需先決定資料來源,避免改錯模型。 |
| 詳細 log table | 建議獨立於 TaskStore 設計 | 詳細 log 屬於 Log Writer / Trace 職責,不宜塞進 TaskStore;建議後續以 DB LogWriter 或 TaskTraceStore 方式處理。 |
4. 為什麼不一次做完
一次完成多表持久化會同時碰到:
- 新增資料表與 schema class。
- 是否修改
TaskNodeExecutionRecordpublic constructor / property。 - 是否讓 TaskStore 直接保存 RawRequest / RawResponse。
- 是否建立交易邊界。
- 是否把詳細 log 變成任務資料的一部分。
- 是否讓 ConsoleHost / ServiceHost 啟動時自動 apply schema。
以上任一項都可能改變資料模型、public contract 或正式 DB 邊界,依 AGENTS.md 規則必須先停下確認。
5. 建議 table 分工
| Table | 職責 | 是否屬 TaskStore | 建議批次 |
|---|---|---|---|
task_executions | 任務主檔與任務狀態摘要 | 是 | 已完成第一版 |
node_executions | Workflow 節點歷程摘要 | 是 | 下一批優先 |
command_executions | Adapter / Device command 執行明細 | 視資料來源決定 | 下一批後段或獨立批次 |
task_log_traces | 任務相關詳細 log / trace | 否,建議屬 Log Writer | 後續批次 |
task_errors | 錯誤快照與例外資訊 | 可選 | 等錯誤查詢需求明確後再做 |
6. node_executions 建議邊界
node_executions 可直接由 TaskExecutionRecord.NodeRecords 產生,因此最適合作為下一個小步。
6.1 建議保存欄位
| 欄位 | 來源 | 第一版建議 |
|---|---|---|
node_execution_id | 程式產生 | 建議用 task_id + sequence_no 或 Guid,需實作前確認。 |
task_id | TaskExecutionRecord.TaskId | 必填。 |
sequence_no | NodeRecords 順序 | 必填,利於重建節點順序。 |
node_id | TaskNodeExecutionRecord.NodeId | 必填。 |
node_name | TaskNodeExecutionRecord.NodeName | 可空。 |
device_id | TaskNodeExecutionRecord.DeviceId | 可空。 |
command_name | TaskNodeExecutionRecord.CommandName | 可空。 |
status | TaskNodeExecutionRecord.Status | 必填。 |
retry_count | TaskNodeExecutionRecord.RetryCount | 必填或預設 0。 |
started_at | TaskNodeExecutionRecord.StartedAt | 必填。 |
ended_at | TaskNodeExecutionRecord.EndedAt | 可空。 |
time_taken_ms | TaskNodeExecutionRecord.TimeTakenMs | 必填或預設 0。 |
error_code | TaskNodeExecutionRecord.ErrorCode | 可空。 |
error_message | TaskNodeExecutionRecord.ErrorMessage | 可空。 |
data_summary | TaskNodeExecutionRecord.DataSummary | 可空,建議 text。 |
metadata_summary | TaskNodeExecutionRecord.MetadataSummary | 可空,建議 text。 |
next_node_id | TaskNodeExecutionRecord.NextNodeId | 可空。 |
transition_summary | TaskNodeExecutionRecord.TransitionSummary | 可空,建議 text。 |
created_at | 寫入當下 | 必填。 |
6.2 建議索引
| Index | Columns | 用途 |
|---|---|---|
idx_node_executions_task_id | task_id | 查詢指定任務節點歷程。 |
idx_node_executions_task_sequence | task_id, sequence_no | 依任務還原節點順序。 |
idx_node_executions_status | status | 查詢失敗或執行中節點。 |
idx_node_executions_device | device_id | 查詢某設備參與的節點。 |
6.3 實作注意
第一版建議只追加保存節點摘要,不要求 FindById / ListRecent 立即完整回填 NodeRecords。
原因是查詢還原多表資料會牽涉:
ITaskStore是否應提供「含明細」查詢模式。ListRecent是否應載入明細,避免大量資料。TaskExecutionRecord.Restore是否應由 Infrastructure.MySql 使用多表資料。
這些都可能影響 public contract 或效能,應另行實作前確認。
7. command_executions 邊界
command_executions 要保存設備命令明細,但目前資料來源需先定義。
| 候選來源 | 優點 | 風險 |
|---|---|---|
TaskNodeExecutionRecord | 已被 TaskStore 持有,可隨 Save 一起處理 | 目前沒有 RawRequestSummary、RawResponseSummary、AdapterTimeTakenMs。若補欄位會改 public constructor / model。 |
WorkflowNodeExecutionSnapshot | 資料最完整,包含 RawRequestSummary / RawResponseSummary / AdapterTimeTakenMs | Snapshot 只在 Workflow callback 當下存在,TaskStore 目前拿不到。 |
LogEntry | 已包含命令與 raw summary,可由 Log Writer 承接 | 屬 Log 流,不是 TaskStore 流;需另建 DB LogWriter 或 TraceStore。 |
建議結論:
- 若命令明細只要「每個節點一筆命令摘要」,可先從
TaskNodeExecutionRecord做簡版,但不保存 RawRequest / RawResponse。 - 若命令明細要包含 RawRequest / RawResponse,建議先設計資料流,不要直接改
TaskNodeExecutionRecord。 - 若未來一個節點可能執行多個 Adapter command,
command_executions不能假設一個 node 只有一個 command。
8. 詳細 log table 邊界
詳細 log table 建議不要由 MySqlTaskStore.Save 負責。
原因:
- TaskStore 的職責是任務狀態與查詢,不是完整 log sink。
- Log 量可能遠大於 Task / Node / Command,會影響 TaskStore 查詢效能。
- 詳細 log 可能需要 level、category、message、raw payload、exception、host、operator、app version,欄位比 TaskStore 更接近
ILogWriter。
建議後續另立:
| 元件 | 職責 |
|---|---|
MySqlLogWriter | 將 LogEntry 寫入 DB。 |
TaskTraceStore | 提供依 TaskId 查詢 log trace 的讀取介面。 |
task_log_traces | 保存任務相關 log / trace,不替代 file log。 |
第一版 detailed log table 建議只保存摘要與診斷欄位,不保存過大的完整 raw payload;若要保存完整 RawRequest / RawResponse,需先定義大小限制與遮蔽規則。
9. 交易策略建議
| 策略 | 適用情境 | 建議 |
|---|---|---|
| 單表 upsert | 目前 task_executions 第一版 | 已完成。 |
task_executions + node_executions 同一 transaction | 保存任務摘要與節點摘要 | 下一批建議。 |
task_executions + node_executions + command_executions 同一 transaction | 命令資料來源明確後 | 後續再做。 |
| log table 獨立寫入 | 詳細 log / trace | 建議獨立,不阻塞 TaskStore Save。 |
node_executions 若與 task_executions 同批保存,建議採「先刪除同 task_id 舊節點,再插入目前 NodeRecords」或「以 task_id + sequence_no upsert」二選一。兩者都會影響 DB 寫入語意,需要實作前確認。
10. Schema / DDL 停止線
以下項目在使用者再次確認前不得執行:
- 建立
node_executions、command_executions、task_log_traces或task_errorstable。 - 修改
task_executions欄位、索引、comment。 - 對真實 DB 執行
CREATE TABLE、ALTER TABLE、DROP TABLE。 - 修改
ITaskStorepublic method 簽章。 - 修改
TaskExecutionRecord/TaskNodeExecutionRecordpublic constructor 或 property。 - 將
MySqlTaskStore接入 ConsoleHost、ServiceHost 或 WebApi 正式啟動流程。
11. 建議下一批實作順序
建議下一批先做「node_executions 實作前確認」,範圍如下:
- 確認
node_executions欄位、索引、comment 與 C# schema class。 - 決定
node_execution_id產生規則。 - 決定
task_id + sequence_no寫入語意:delete-and-insert 或 upsert。 - 先實作 SQL Builder / fake gateway 測試,不連真實 DB。
- 不修改
ITaskStorepublic method 簽章。 - 不要求
FindById/ListRecent立即載入節點明細。 - 完成後再討論
command_executions的資料來源。
12. 本次建議結論
建議採用「先節點、再命令、最後詳細 log」:
node_executions是 TaskStore 下一批最合理的小步,因為目前資料來源已在TaskExecutionRecord.NodeRecords。command_executions需要先確認 RawRequest / RawResponse 資料來源,不宜直接改 public model。- 詳細 log table 應獨立走 DB LogWriter / TraceStore,不應放進
MySqlTaskStore.Save。
建議下一步做「MySQL TaskStore node_executions 實作前確認」,先固定欄位、索引、交易策略與測試範圍。