[GODRIVER-1454] Make Session interface implementable by external packages Created: 01/Jan/20  Updated: 10/Jan/20  Resolved: 10/Jan/20

Status: Closed
Project: Go Driver
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Kaustubh Mallik Assignee: Isabella Siu (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hi,

I am using the Session interface to implement transactions. Now, there are several fallback logic in it, which aborts the transaction. Now, in order to simulate those failure behaviors, I was trying to have a mock implementation of the Session interface, but as there is an unexported function session() which inhibits it, the last one.

https://github.com/mongodb/mongo-go-driver/blob/master/mongo/session.go#L92

// Session is the interface that represents a sequential set of operations executed.
// Instances of this interface can be used to use transactions against the server
// and to enable causally consistent behavior for applications.
type Session interface {
   EndSession(context.Context)
   WithTransaction(ctx context.Context, fn func(sessCtx SessionContext) (interface{}, error), opts ...*options.TransactionOptions) (interface{}, error)
   StartTransaction(...*options.TransactionOptions) error
   AbortTransaction(context.Context) error
   CommitTransaction(context.Context) error
   ClusterTime() bson.Raw
   AdvanceClusterTime(bson.Raw) error
   OperationTime() *primitive.Timestamp
   AdvanceOperationTime(*primitive.Timestamp) error
   Client() *Client
   session()
}

I strongly believe there must be a design decision for keeping it that way, but can you just tell me a little bit about it, or maybe point in the right direction. Also, is it at all possible to make it an exported function, so the users of this package can have their own custom implementation of the Session interface? If it is indeed possible, I would love it if I can be of any help in this change.

Also, can you suggest me some ways in which I can simulate the failure behavior of transaction,  I would be really thankful.

 



 Comments   
Comment by Kaustubh Mallik [ 09/Jan/20 ]

Hi Isabella, thanks a lot for taking out time for responding and sharing the doc and snippets. I guess I have all that I need to proceed. Please go ahead and close it. 

Comment by Isabella Siu (Inactive) [ 08/Jan/20 ]

Hi kaustubhmallik@gmail.com,

Due to the complexity of the Session interface, we've chosen not to make it implementable by users. Another way that you can simulate a transaction failure would be to set a fail point on the mongod or mongos.

You can simulate the failure of a transaction with a fail point (documentation at https://github.com/mongodb/mongo/wiki/The-%22failCommand%22-fail-point). Fail points can be set through the both the shell and the driver. A go driver example of setting a fail point to fail on commitTransaction commands and close the connection is:

fp := bson.D{
 {"configureFailPoint", "failCommand"},
 {"mode", "alwaysOn"},
 {"data", bson.D{
   {"failCommands", bson.A{"commitTransaction"}},
   {"closeConnection", true},
 }},
}
 
admin := client.Database("admin")
_ = admin.RunCommand(context.Background(), fp)

 Different options give different failure behavior, for example this failpoint would fail commitTransaction commands with an errorCode of 2:

bson.D{
 {"configureFailPoint", "failCommand"},
 {"mode", "alwaysOn"},
 {"data", bson.D{
   {"failCommands", bson.A{"commitTransaction"}},
   {"errorCode", 2},
 }},
}

 

Generated at Thu Feb 08 08:36:26 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.