Repository navigation
Give the event-batching slot ownership (closes #3217) - #3236
Conversation
Pragmatic Code Review: PR #3236 (closes #3217): give the event-batching slot ownershipReview TypeInitial review. The PR had no earlier reviews or comments. SummaryThe PR replaces the single service-wide
This removes a whole class of cross-task bugs rather than patching one. A plain write can no longer land in, or be discarded with, another task's transaction. The Requirements Check
Verification of the key risk areas
Code Review Findings🔴 CriticalNone. 🟡 Improvements
🟢 Nits
RecommendationAPPROVE. The design is correct and simpler, every acceptance criterion is met with tests that fail on the old code, and I found no transactional emit site that was missed. I'd recommend the |
malibio
left a comment
There was a problem hiding this comment.
Automated pragmatic-code-review: APPROVE (posted as a comment — GitHub blocks self-approval). Full findings in the review comment above.
Review addressed✅ 🟡 emit_event inside a transaction: a Re-review decision: NO RE-REVIEW NEEDED. Changes are a debug-only assertion with its own test plus doc wording; no production logic changed. |
A transaction's events are buffered on its own NodeServiceTx (reached via emit_event_in_tx) instead of a shared Transactional slot, so a non-transactional write's event can never be buffered into, or discarded with, another task's transaction. begin_batch_emit opens a token-identified batch owned by the opening task; any number may be open, an event joins its own task's batch (else the most recently opened one), and each guard flushes only its own. A transaction reserves a sequence number under the write guard, so a batch keeps the later commit's event for a node even when two commits publish out of order. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- task_local IN_TRANSACTION scoped around the with_transaction closure; emit_event debug_asserts it is unset (regression test added) - next_seq doc states the guarantee holds between transactions only - test doc and crud.rs doc wording Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ceac546 to
208b3ce
Compare
Closes #3217.
What
The single service-wide
BatchStateslot recorded what mode emission was in, not who owned it. This replaces it with owned buffers:NodeServiceTx. In-tx code emits viaemit_event_in_tx(tx, …)→tx.buffer_event(..); plainemit_eventand the store notifier never consult a transaction. A non-tx write notifying after releasing the write guard can no longer be buffered into (and discarded by) another task's rollback. No moreTransactionalstate, parking, orResetOnDrop.begin_batch_emitopens a batch keyed by a token and the opening tokio task (thread outside a task). Any number may be open; a node event joins its own task's most recent batch, else the most recently opened batch (so single-batch behaviour — and the sync page-guard contract — is unchanged). Each guard flushes only its own batch; the nested-guarddebug_asserts are gone.with_transaction=run_transaction+publish_committed; a sequence number is reserved while the write guard is held, and a batch keeps the highest-seq event per node, so two commits publishing out of order still leave the later snapshot.All in-transaction emit sites (crud/bulk/hierarchy/relationship/schema, incl. the four hierarchy
emit_*helpers) now taketx.Tests
a_rolled_back_transaction_never_takes_another_writers_event,concurrent_batch_guards_each_deliver_only_their_own_events(both drop orders + same-task nesting),batch_keeps_the_later_commit_when_commits_publish_out_of_order.emit_event_in_tx);bulk_invariant_dispatch_test14/14.nodespace-corelib (1932) + integration tests pass;quality:fixclean.Docs
ADR-069 §2 rewritten in nodespace-docs (45dad48) to describe the ownership model.
🤖 Generated with Claude Code