Skip to content

fix: serialize concurrent MongoStore operations - #800

Open
hiohiohio wants to merge 1 commit into
quickfixgo:mainfrom
hiohiohio:codex/mongo-store-serialization
Open

hiohiohio wants to merge 1 commit into
quickfixgo:mainfrom
hiohiohio:codex/mongo-store-serialization

Conversation

@hiohiohio

Copy link
Copy Markdown

Summary

Fixes #799.

An application goroutine calling SendToTarget() can persist an outgoing message while the session goroutine advances the incoming sequence number on the same MongoStore. This can abort the outbound transaction with WriteConflict and cause data races on the sequence cache.

Changes

  • Add a mutex per MongoStore to serialize database writes and related cache access.
  • Hold the mutex across message persistence, sequence updates, transaction commit, and cache updates.
  • Protect sequence/time reads and Reset/Refresh with the same mutex, using internal helpers to avoid recursive locking.
  • Keep message-iteration callbacks outside the mutex.

The API and database schema are unchanged. Synchronization is limited to one Store instance; it does not coordinate separate instances or processes. Operations using this mutex wait during database I/O.

Validation

Tested with Go 1.27.4 and MongoDB 7.0.48 configured as a replica set.

  • The new regressions reproduce WriteConflict and cache data races against the original implementation at eff945dd59a41caeaed20f71916f08d37e0fda99 using a source overlay.
  • go test -mod=readonly -race ./store/mongo -v -count=1 passed with MONGODB_TEST_CXN set to the real replica set.
  • go vet -mod=readonly ./store/mongo and git diff --check passed.

Coverage includes transactions enabled/disabled, concurrent send/receive, Reset/Refresh overlap, sequence reads, persisted state and message consistency, and lock release after insert/update/commit failures.

Full-repository tests and MongoStore TCP E2E tests were not run for this patch.

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.

MongoStore: concurrent send and receive operations can cause WriteConflict and sequence cache races

1 participant