Skip to content

mongo: fence the result landing against a lost dispatch lock (pre-keystone, INV3) #360

Description

@as535364

背景: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 寫入,兩邊都會回 LANDEDcomplete_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。

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions