Skip to content

ops: refuse same-key writes from other threads during an operation; batch failure notes (#5) - #6

Merged
thorwhalen merged 3 commits into
masterfrom
fix/ops-concurrent-and-batch-5
Oct 13, 2026
Merged

thorwhalen merged 3 commits into
masterfrom
fix/ops-concurrent-and-batch-5

Conversation

@thorwhalen

@thorwhalen thorwhalen commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Closes #5.

  1. Other thread, during the operation. `cosmodol.routing` keeps a registry of pending redirects. A write of the same leaf key arriving from a context with no redirect (another thread, or a task that did not copy the context) while an operation on that key is pending now raises `ConcurrentWriteError` (a `RedirectError`) before it acts, instead of running as an ordinary upsert/delete outside the operation's checks. Other keys are untouched, so unrelated writers sharing the leaf are not refused (the concern that ruled out a leaf-wide registry). Cost: an unrelated writer of the same key during the (short) window gets a retryable error.
  2. Later writes (a write-behind buffer flushing after the operation ended) are indistinguishable from any other writer's: not preventable. The operation already raises `RedirectError` when the write never reached the leaf; docs now state exactly this boundary.
  3. `batch_items` side effects before commit. If the commit fails on a wrapped store, the exception carries a note (`notes`) naming the keys the layers had already acted on (caches/audit logs may disagree with the container). A two-phase opt-in protocol was not added: no layer in the fleet would use it.

Tests: threaded layer refused and nothing written; other keys / after the window allowed; failed batch note. Doctest for the threaded case in `routing.py`.

Review: fresh Opus adversarial review confirmed one blocking defect (Redirect dataclass compared by equality, which reads whole stores under the registry lock and could remove another thread's entry), plus the batch note skipping subclassed leaves and an over-sure wording. All fixed with tests; docs now also name the different-leaf-object limit. Fixes are small and local; not re-reviewed.

🤖 Generated with Claude Code

thorwhalen and others added 3 commits October 13, 2026 23:09
…tch failure names the keys layers acted on (#5)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… leaves (review of #6)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@thorwhalen
thorwhalen merged commit b1d1082 into master Oct 13, 2026
12 checks passed
@thorwhalen
thorwhalen deleted the fix/ops-concurrent-and-batch-5 branch October 13, 2026 23:18
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.

ops: writes a layer performs in another thread or later, and batch side effects before commit, escape the redirect

1 participant