feat(ops-runs): expire claims that keep losing their lease
Lapsed claims were reopened with no attempt ceiling, so a run whose worker lost its lease (including a 409 before dispatch) could cycle forever. Activity Core now reopens a lapsed claim below OPS_RUN_MAX_ATTEMPTS and sets terminal 'expired' at the ceiling. The owner is kept for audit, and /ops-runs/expire-leases reports reopened and expired counts. Answers the REINAH-WP-0003-T05 open point on thread 27cd4c47 (ACTIVITY-WP-ADHOC-2026-10-19). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 244572@bnt-lap001 Assistant-Session: 3b235e1a-ae45-4d0f-ae70-17a9bd78ece8
This commit is contained in:
parent
3b25aea7b0
commit
42347da012
6 changed files with 192 additions and 14 deletions
|
|
@ -61,7 +61,14 @@ workplan task file. Not an issue-core or Forgejo ticket.
|
|||
- `labels_mode`: `any` (default) — run must contain at least one listed label;
|
||||
`all` — run must contain every listed label; omit `labels` to claim any open run.
|
||||
- Claim uses `FOR UPDATE SKIP LOCKED` for concurrency safety.
|
||||
- Stale claims (`state=claimed` and `lease_until <= now()`) are reopened before select.
|
||||
- Stale claims (`state=claimed` and `lease_until <= now()`) are recovered by
|
||||
Activity Core before every claim select and by `POST /ops-runs/expire-leases`
|
||||
(returns `{"reopened": n, "expired": m}`). Below `OPS_RUN_MAX_ATTEMPTS` the row
|
||||
returns to `open` with owner and lease cleared; at the ceiling it becomes
|
||||
terminal `expired` (owner kept for audit, `result.error` set). A worker whose
|
||||
lease was lost, including one that got a 409 before dispatch, must not close
|
||||
the row; it leaves recovery to this expiry path. A late close on an expired
|
||||
row is refused as `state_conflict`.
|
||||
- Heartbeat, complete, and fail lock the row and require an active lease
|
||||
(`lease_until > now()`). An expired worker cannot revive or close its claim.
|
||||
- A first terminal close returns `close_disposition: applied`. If its response
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue