Skip to content

feat(session): optimistic locking for concurrent refinement races - #122

Merged
CodeNinjaSarthak merged 1 commit into
mainfrom
feat/refine-optimistic-lock
May 3, 2026
Merged

feat(session): optimistic locking for concurrent refinement races#122
CodeNinjaSarthak merged 1 commit into
mainfrom
feat/refine-optimistic-lock

Conversation

@CodeNinjaSarthak

Copy link
Copy Markdown
Owner

Changes

  • RefinementInProgressError — new exception, maps to 409 at route layer
  • RedisSessionStore.acquire_lock()SET NX PX primitive, returns bool
  • RedisSessionStore.release_lock()DEL primitive
  • Lock acquired in refine() after all validation guards, before state mutation
  • Lock released in _run_refinement() finally block — guaranteed on success and failure
  • REFINE_LOCK_TTL_MS = 120_000 — 2 min TTL as safety net if process dies mid-run

Failure mode

Second concurrent POST /refine → 409 Conflict immediately, no state mutation, no phantom pipeline run.

Tests

46 passing, mypy clean. 4 new tests:

  • lock conflict → RefinementInProgressError raised, state unchanged
  • lock released after success
  • lock released after failure
  • route returns 409

Closes #103

…t races

- Add RefinementInProgressError exception class
- Add REFINE_LOCK_TTL_MS = 120_000 (2 min TTL covers worst-case pipeline)
- Add acquire_lock() and release_lock() to RedisSessionStore using SET NX PX
- Acquire lock in refine() after all validation guards, before state mutation
- Release lock in _run_refinement() finally block — always runs on success
  and failure
- Add 409 catch for RefinementInProgressError in POST /refine route handler
- 4 new tests (Section 11): lock conflict, release after success, release
  after failure, 409 route response — 46 total passing, mypy clean

Closes #103
@CodeNinjaSarthak
CodeNinjaSarthak merged commit b060501 into main May 3, 2026
2 checks passed
@CodeNinjaSarthak
CodeNinjaSarthak deleted the feat/refine-optimistic-lock branch May 3, 2026 14:07
CodeNinjaSarthak added a commit that referenced this pull request May 5, 2026
…t races (#122)

- Add RefinementInProgressError exception class
- Add REFINE_LOCK_TTL_MS = 120_000 (2 min TTL covers worst-case pipeline)
- Add acquire_lock() and release_lock() to RedisSessionStore using SET NX PX
- Acquire lock in refine() after all validation guards, before state mutation
- Release lock in _run_refinement() finally block — always runs on success
  and failure
- Add 409 catch for RefinementInProgressError in POST /refine route handler
- 4 new tests (Section 11): lock conflict, release after success, release
  after failure, 409 route response — 46 total passing, mypy clean

Closes #103
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refine(): add optimistic locking to prevent concurrent refinement races

1 participant