第三部從併發模型選擇,講到局部重試、進度呈現、退避策略、合併前驗證、數量異常處理,表面上主題很分散,但串起來看,每一天處理的都是同一個問題的不同面向:下載引擎的每一層,失敗的方式各自不同,處理方式也要各自對應設計,不能用同一套「try/except 包起來重來」打發所有情況。
| 層級 | 可能的失敗方式 | 處理方式 |
|---|---|---|
| 單一片段下載 | 網路請求失敗 | 局部重試,有上限(Day 12) |
| 重試時機 | 立刻重試造成尖峰負載 | 固定間隔退避(Day 19) |
| 個別片段最終失敗 | 重試上限用完仍失敗 | 記錄下來,不中斷其他片段(Day 12) |
| 合併前 | 片段數量比預期少 | fail fast,明確中斷並報錯(Day 20) |
| 合併前 | 片段數量比預期多 | 保守地全部刪除重來(Day 21) |
這張表格本身就是這七天內容的濃縮:不同層級的失敗,需要不同的處理策略,沒有一套萬用公式。
回顧這七天的每一個案例,會發現一個共通點:每一種失敗處理方式,都對應著「這一層的失敗代表什麼、下一步該怎麼辦」這個具體問題的答案,而不是隨手加一層 try/except 把錯誤蓋住。先想清楚每一層可能怎麼失敗、失敗之後系統該處於什麼狀態,再決定要重試、要中斷、還是要清理重來——這是設計的一部分,不是寫完主要邏輯之後才補上去的附加品。
到這裡為止,第三部講的都是「怎麼設計失敗處理」,但還沒回答一個問題:這些精心設計的重試、驗證、清理邏輯,怎麼確認它們在各種失敗情境下真的會按照預期運作? 這正是第四部要處理的:怎麼測試一段充滿外部依賴(網路、檔案系統、加密)的程式碼,包含怎麼模擬出「失敗」這種不容易在真實環境裡穩定重現的情境。
第四部開始:測試網路請求,怎麼手刻一個 async mock response,而不用真的發一次網路請求。