Skip to content

Conversation

@scmsscm
Copy link

@scmsscm scmsscm commented Nov 19, 2025

Inspired by https://github.com/coinbase/mongobetween/pull/76/files but rewritten from scratch with TDD.

Summary

Implements full MongoDB read preference support in mongobetween, allowing clients to specify which replica set members should handle read operations.

Motivation

Closes #76 (previous incomplete attempt)

Currently, mongobetween hardcodes read preference to primary for all operations. This prevents applications from leveraging secondaries for read scaling.

Changes

  • Added ReadPref() method to Operation interface
  • Implemented read preference extraction from MongoDB wire protocol ($readPreference field)
  • Updated selectServer() to accept and use client-specified read preferences
  • Supports all 5 MongoDB read preference modes: primary, primaryPreferred, secondary, secondaryPreferred, nearest
  • Maintains correct priority: transaction pinning > cursor pinning > read preference > default to primary

Testing

✅ 14 new unit tests covering all read preference modes and edge cases
✅ All tests passing
✅ Zero linter errors
✅ Build successful

Test output:

go test -v ./mongo -run ReadPref
=== RUN   TestExtractReadPref_Primary
--- PASS: TestExtractReadPref_Primary (0.00s)
=== RUN   TestExtractReadPref_Secondary
--- PASS: TestExtractReadPref_Secondary (0.00s)
=== RUN   TestExtractReadPref_SecondaryPreferred
--- PASS: TestExtractReadPref_SecondaryPreferred (0.00s)
=== RUN   TestExtractReadPref_PrimaryPreferred
--- PASS: TestExtractReadPref_PrimaryPreferred (0.00s)
=== RUN   TestExtractReadPref_Nearest
--- PASS: TestExtractReadPref_Nearest (0.00s)
=== RUN   TestExtractReadPref_NoReadPreference
--- PASS: TestExtractReadPref_NoReadPreference (0.00s)
=== RUN   TestExtractReadPref_InvalidMode
--- PASS: TestExtractReadPref_InvalidMode (0.00s)
=== RUN   TestExtractReadPref_MalformedDocument
--- PASS: TestExtractReadPref_MalformedDocument (0.00s)
=== RUN   TestOpMsg_ReadPref_Primary
--- PASS: TestOpMsg_ReadPref_Primary (0.00s)
=== RUN   TestOpMsg_ReadPref_Secondary
--- PASS: TestOpMsg_ReadPref_Secondary (0.00s)
=== RUN   TestOpMsg_ReadPref_NoPreference
--- PASS: TestOpMsg_ReadPref_NoPreference (0.00s)
=== RUN   TestOpQuery_ReadPref
--- PASS: TestOpQuery_ReadPref (0.00s)
PASS
ok      github.com/coinbase/mongobetween/mongo  0.359s

## Documentation
- Inline code comments
- Full test coverage

## Backward Compatibility
✅ Fully backward compatible - defaults to primary when no preference specified

## References
- [MongoDB Read Preference Specification](https://www.mongodb.com/docs/manual/core/read-preference/)
- [Server Selection Spec](https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.rst)

- Implement ReadPref() method for all operation types
- Extract read preferences from wire protocol messages
- Update selectServer to use client read preferences
- Add comprehensive test suite (14 tests, all passing)
- Maintain backward compatibility
@cb-heimdall
Copy link

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants