背景:INV3(單寫者)目前由 dispatch/job.py 的 per-submission lock 保證,landing 期間有 watchdog 持續續期(Back-End#358 的 6d616a5),所以「Mongo 慢寫入」這條路已經關死。
殘餘缺口:lock key 本身蒸發時(Redis 資料遺失,或行程停滯久到 watchdog 續期失敗)。_keep_lock_alive 只能記錄 landing lock lost mid-write 並退出——dispatch 層無法中止一個已在飛行中的黑盒 land_result,新的 caller 這時能重新取得 lock 並進入第二次 Mongo 寫入,兩邊都會回 LANDED。complete_finish 的 delete-after-write 只清得掉 Redis,擋不住已開始的第二次寫入。
要真正關死,需要在 Mongo 端做守衛,而不是在 dispatch 層再加防護。
範圍:mongo/submission.py landing 路徑。方向擇一(實作時定案):
- Fencing token:dispatch 在
complete_begin 產生單調遞增的 token 隨 landing 傳入;Mongo 端條件式寫入,只接受 token ≥ 已記錄值,舊 writer 的寫入被拒。
- Conditional write:以 job_id / 版本欄位做
find_one_and_update 的條件,非當前 job 的結果寫不進去。
兩者都需要 dispatch/ 配合傳遞 token/job_id,屬於跨層設計,故標 ready-for-human:先定案再拆實作票。
Done:
- 選定方案並記錄(spec §6 或新 ADR)。
- 有測試模擬「lock 蒸發 → 新舊 writer 並行」,斷言只有一份結果落地。
- dispatch 端
_keep_lock_alive 的 docstring 殘餘說明可以移除。
依賴:無;但必須早於 keystone 接線(Normal-OJ/Normal-OJ#66)。與 Back-End#359(process_result 冪等化)同屬 landing 硬化,建議一併設計。
參考:Back-End#358 review thread、ADR-0003、spec §6 INV3。
背景:INV3(單寫者)目前由
dispatch/job.py的 per-submission lock 保證,landing 期間有 watchdog 持續續期(Back-End#358 的6d616a5),所以「Mongo 慢寫入」這條路已經關死。殘餘缺口:lock key 本身蒸發時(Redis 資料遺失,或行程停滯久到 watchdog 續期失敗)。
_keep_lock_alive只能記錄landing lock lost mid-write並退出——dispatch 層無法中止一個已在飛行中的黑盒land_result,新的 caller 這時能重新取得 lock 並進入第二次 Mongo 寫入,兩邊都會回LANDED。complete_finish的 delete-after-write 只清得掉 Redis,擋不住已開始的第二次寫入。要真正關死,需要在 Mongo 端做守衛,而不是在 dispatch 層再加防護。
範圍:
mongo/submission.pylanding 路徑。方向擇一(實作時定案):complete_begin產生單調遞增的 token 隨 landing 傳入;Mongo 端條件式寫入,只接受 token ≥ 已記錄值,舊 writer 的寫入被拒。find_one_and_update的條件,非當前 job 的結果寫不進去。兩者都需要
dispatch/配合傳遞 token/job_id,屬於跨層設計,故標ready-for-human:先定案再拆實作票。Done:
_keep_lock_alive的 docstring 殘餘說明可以移除。依賴:無;但必須早於 keystone 接線(Normal-OJ/Normal-OJ#66)。與 Back-End#359(
process_result冪等化)同屬 landing 硬化,建議一併設計。參考:Back-End#358 review thread、ADR-0003、spec §6 INV3。