[GODRIVER-2035] Causal Consistency by default Created: 02/Jun/21  Updated: 13/Jul/23

Status: Backlog
Project: Go Driver
Component/s: Connections
Affects Version/s: 1.5.1, 1.5.2, 1.5.3
Fix Version/s: None

Type: New Feature Priority: Minor - P4
Reporter: Matt Hartstonge Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: mgocompat
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

go1.16.4
windows
linux


Attachments: PNG File default-best-practice-causal-consistency-params.png     PNG File image-2021-06-02-17-24-25-948.png     PNG File image-2021-06-04-11-09-14-247.png     PNG File new-client-default-settings.png     PNG File new-session-client-default-settings.png     PNG File new-session-client-session-defaults.png    
Issue Links:
Related
related to DRIVERS-1798 Add read/write concern options on a s... Backlog
Quarter: FY24Q3
Backwards Compatibility: Fully Compatible
Documentation Changes Summary:

1. What would you like to communicate to the user about this feature?
2. Would you like the user to see examples of the syntax and/or executable code and its output?
3. Which versions of the driver/connector does this apply to?


 Description   

From my understanding of reading the Go driver code documentation and mongo docs client drivers should, by default, be set to use causal consistency:

I've noticed in the Go(lang) driver, when creating a new client or creating a new session, both read concern and write concern are set to empty, but CausalConsistency/Consistent is set to true by default.

According to the go driver docs:

New Client:

New Session:

The `session.ClientSession.Consistent` property by default is set to true.

So should the driver by default, be setting the "best practice" causal consistency preferences?

OR when calling `client.StartSession(options.Session().SetCausalConsistency(true))` should this be setting default majority read and write concerns?

Current implementation of `mongo/options/sessionoptions.go#ln51`

// SetCausalConsistency sets the value for the CausalConsistency field.
func (s *SessionOptions) SetCausalConsistency(b bool) *SessionOptions {
   s.CausalConsistency = &b
   return s
}

 

 

Suggested Implementation?

// SetCausalConsistency sets the value for the CausalConsistency field.
func (s *SessionOptions) SetCausalConsistency(b bool) *SessionOptions {
   s.CausalConsistency = &b
   s.DefaultReadConcern = readconcern.Majority()
   s.DefaultWriteConcern = writeconcern.New(writeconcern.WMajority())
   return s
}

 



 Comments   
Comment by Kevin Albertson [ 22/Jun/21 ]

Thank you for the additional context! We will wait for the conclusion of DRIVERS-1798 before considering the change in the Go driver, so we do not introduce behavior that diverges from the specification.

Comment by Matt Hartstonge [ 04/Jun/21 ]

Oh wow!
Okay cool.
Thanks for that. 😃

But yes - this feature is pretty key for us.

Working with API driven web services, every API endpoint starts its own session to keep it's operations isolated within a go routine (thread). With the mgo driver, you were able to dynamically change the concerns at the session level for where we knew a certain set of operations required higher consistency guarantees.

So, given Middlewares > Handlers > Datastore Layer.

We pass a mongo session throughout the lifecycle of the API request via `context.Context`. It may not be until you get down into the datastore layer where we are needing to define these concerns when performing a given set of operations across a number of documents within a given or across multiple collections.
Vice versa, at the handler level you may need to define a session as you know you will be making multiple datastore layer requests, for a terrible pseudocode example:

 

 

sess := session.New(context.Background())
defer sess.Close()
 
ctx := session.ToContext(sess)
doc := datastore.Records.Get(ctx, 123) // <-- could mutate the provided session in the context...
 
doc.UpdatedAt = time.Now().Unix()
doc, updateLinkedGroup = magicalBusinessLogic(ctx , doc) // <-- could mutate the provided session in the context...
if updateLinkedGroup { 
    datastore.Groups.UpdateDocLink(ctx, doc) 
}
 
doc = datastore.Records.UpdateRecord(ctx , doc)
 

 

Comment by Kevin Albertson [ 04/Jun/21 ]

Hi matt@linc-ed.com, thank you for the feature request!

From my understanding of reading the Go driver code documentation and mongo docs client drivers should, by default, be set to use causal consistency:

That is correct. By default, causal consistency is enabled on explicit sessions.

Note, the DefaultReadConcern, DefaultReadPreference, and DefaultWriteConcern only apply to transactions started with the session. These do not apply to non-transaction operations. There is currently no way to specify a read/write concern for non-transaction operations within a session.

Based on what I can tell, the driver runs with mongo read/write concern defaults, that is a read concern of "local" and a write concern of "
Unknown macro: {w}
", which based on my reading of the following table, provides no causal consistency guarantees, even though the causal boolean is set:

It is true that there are no strict guarantees because of scenarios like having a network partition. But enabling causal consistency does still change the behavior even with the default write and read concerns. E.g. reading from a secondary with readConcern: "local" on a session with causal consistency will wait for that secondary to replicate up to the latest logical time on that session before responding with results.

As far as current options go, the readConcern and writeConcern that is sent from the driver can be set at the Client/Database/Collection level as a workaround. If none is set in the driver, then the default will be based on the server defaults, which is currently w:1 and readConcern:"local".

Since the driver session API is specified as a cross-driver API I have created DRIVERS-1798 to consider adding read/write concern as part of the session options as a cross-drivers change.

Comment by Matt Hartstonge [ 03/Jun/21 ]

Based on what I can tell, the driver runs with mongo read/write concern defaults, that is a read concern of "local" and a write concern of "{w: 1}", which based on my reading of the following table, provides no causal consistency guarantees, even though the causal boolean is set:

Comment by Matt Hartstonge [ 02/Jun/21 ]

Oh no! It dropped the pictures :sadface:

Here's what the order of pictures should be:

  1. default-best-practice-causal-consistency-params.png
  2. image-2021-06-02-17-24-25-948.png
  3. new-client-default-settings.png
  4. new-session-client-default-settings.png
  5. new-session-client-session-defaults.png
Generated at Thu Feb 08 08:37:41 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.