fix(store): synchronize mutable writes by admitted batch - #762
Merged
matt-ramotar merged 6 commits intoSep 8, 2026
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #762 +/- ##
==========================================
+ Coverage 80.81% 83.53% +2.72%
==========================================
Files 41 42 +1
Lines 912 899 -13
Branches 174 170 -4
==========================================
+ Hits 737 751 +14
+ Misses 107 91 -16
+ Partials 68 57 -11
🚀 New features to boost your workflow:
|
Signed-off-by: Matt Ramotar <matt.ramotar@icloud.com>
Signed-off-by: Matt Ramotar <matt.ramotar@icloud.com>
Signed-off-by: Matt Ramotar <matt.ramotar@icloud.com>
Signed-off-by: Matt Ramotar <matt.ramotar@icloud.com>
Signed-off-by: Matt Ramotar <matt.ramotar@icloud.com>
matt-ramotar
force-pushed
the
matt-ramotar/fix-761-mutable-store-synchronization
branch
from
September 8, 2026 20:10
72961ae to
0274288
Compare
matt-ramotar
marked this pull request as ready for review
September 8, 2026 20:19
Signed-off-by: Matt Ramotar <matt.ramotar@icloud.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #761.
Overlapping writes for one key can currently lose B when A replaces the pending queue, or let an older eager success acknowledge B even though B's update failed. This change keeps stable per-key state and acknowledges only the admitted entries captured before each post. Explicit writes and eager retries share server synchronization, while B can still persist locally during A's network call.
Pending entries use identity rather than request timestamps or equality, and coalesced callers receive the saved server result. Cancellation propagates while retaining admitted work. Success callbacks run after locks and adapter context exit, and callback or bookkeeping failures cannot undo acknowledgment. Inherited recursive adapter operations for the same store and key are rejected before nested effects.
The published version is now
5.1.0-alpha12in the shared version catalog. Generated JVM and Kotlin Multiplatform Maven metadata, including Store project dependencies, resolve to alpha12.Validation (synchronization implementation
0274288d770eca167ddcfaf94c461141aea48892; version-only follow-updb1b957c9f8bae2e52304c36b5587e6eb166e9a9):fde07551688ae7f1e22a8da77f6cbcde1454f384: both deterministic issue tests executed and failed.newerWriteSurvivesAcknowledgementCommitreturned an error for B;olderEagerSuccessDoesNotAcknowledgeNewerFailedWritedelivered B's callback once when the expected count was zero. The log, XML, report, fixture, and test source were archived before implementation. Both tests now pass../gradlew :store:jvmTest --rerun-tasks --no-build-cache --console=plain../gradlew :store:apiCheck :store:ktlintCheck :store:spotlessCheck --console=plainpassed. The JVM API baseline is unchanged../gradlew :store:iosSimulatorArm64Test --rerun-tasks --no-build-cache --console=plain. Native XML includes all 12 acknowledgment tests, 20 lifecycle tests, both contention tests, and all 9 barrier tests; the test executable ran.db1b957c9f8bae2e52304c36b5587e6eb166e9a9, including the full build, tests, and coverage upload: CI run../gradlew :store:generatePomFileForJvmPublication :store:generatePomFileForKotlinMultiplatformPublication --console=plain; both Store publications and their core/cache/multicast dependency coordinates use5.1.0-alpha12.The synchronization scope remains one MutableStore instance. Fetch-after-failed-push policy, cross-instance coordination, concurrent clear semantics, and durable outbox behavior are unchanged. The version advances from the already-tagged
5.1.0-alpha11to5.1.0-alpha12.Note
High Risk
Changes core MutableStore concurrency, acknowledgement, and cancellation semantics plus SourceOfTruth write barriers—areas where subtle races or callback reentrancy can cause data loss or deadlocks if wrong.
Overview
Fixes overlapping MutableStore writes for one key that could drop pending work or acknowledge failed updates incorrectly.
RealMutableStore replaces the per-key write queue and
ThreadSafetylocks withMutableStoreKeyState(separate local vs remote mutexes, identity-based pending entries). Writes persist locally, thensynchronizeposts the latest snapshot and acknowledges only entries captured in that batch—coalescing callers share one server result. Explicit writes and read-time eager retries share the same path;Bookkeepermarkers integrate with snapshot selection.Adds
MutableStoreAdapterContextto reject recursive read/write/clear on the same store/key during adapter/updater/bookkeeper work, documents lifecycle rules onMutableStore, and runs success callbacks after locks release (with isolated failure handling).SourceOfTruthWithBarrier and
RealStore.writenow propagateCancellationExceptionand always reopen/release barriers on cancelled writers.ThreadSafetyis removed.Large new test coverage: acknowledgement races, lifecycle/cancellation, concurrency (all writes must succeed), and barrier cancellation.
Reviewed by Cursor Bugbot for commit 0274288. Bugbot is set up for automated code reviews on this repo. Configure here.