Skip to content

mongo: make process_result tolerate re-invocation (pre-keystone, spec 17.2) #359

Description

@as535364

背景:pull-based dispatch 的 landing 契約是 at-least-once,不是 exactly-once。dispatch/job.pycomplete_job 會在兩種情況重呼叫注入的 landing callable:

  1. lease 過期 → reclaim → 換一台 runner 重跑整份 submission(既有系統本來就會發生);
  2. landing 寫到一半拋例外 → complete_restore 還原 leased → runner 依 retry 規則重送 → 全量重跑,不是接續。

第 2 點在 Back-End#358 的 review 被指出:目前 Submission.process_resultupdate() 寫 Submission,再由 finish_judging() 累加 User 計數、append homework 的 submissionIds,分多次 save 且無交易保護。後段 save 失敗時,重試會重複前段已成功的副作用(計數被灌兩次、submissionIds 出現重複)。

dispatch/ 端已用 test_complete_retry_after_partial_write_reinvokes_in_full 把這個語意釘在 seam 上——該測試明確斷言副作用會發生兩次,由 mongo 端吸收。

範圍mongo/submission.pyprocess_result / finish_judging,以及它們碰到的 UserHomework.student_status。不動 dispatch/

Done:

  • process_result 對「完整重跑」與「partial write 後全量重試」皆冪等:重複執行後 User 計數、homework submissionIdsstudent_status 與只執行一次的結果相同。
  • 有測試涵蓋:同一 submission 連續 process_result 兩次;以及在 finish_judging 中途注入例外後重試。
  • 若改用 set/upsert 語意取代累加,需確認既有 rejudge 路徑行為不變。

依賴:無,可獨立進行;但必須早於 keystone 接線(Normal-OJ/Normal-OJ#66)。
參考:spec §17.2「process_result 重算容忍性」、ADR-0003 Consequences、Back-End#358 review thread。

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, ready for an AFK agent

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions