From 830577123bde187dca994f9c4cd0e53bc32cf6b0 Mon Sep 17 00:00:00 2001 From: Matt Dale <9760375+matthewdale@users.noreply.github.com> Date: Mon, 28 Aug 2023 15:45:50 -0700 Subject: [PATCH] GODRIVER-2962 Remove setters from AbortTransaction and CommitTransaction. --- mongo/session.go | 35 ++- x/mongo/driver/operation/abort_transaction.go | 195 ++++------------- .../driver/operation/commit_transaction.go | 201 +++++------------- 3 files changed, 119 insertions(+), 312 deletions(-) diff --git a/mongo/session.go b/mongo/session.go index 22aa026c9e..27c9b26dae 100644 --- a/mongo/session.go +++ b/mongo/session.go @@ -293,10 +293,20 @@ func (s *sessionImpl) AbortTransaction(ctx context.Context) error { selector := makePinnedSelector(s.clientSession, description.WriteSelector()) s.clientSession.Aborting = true - _ = operation.NewAbortTransaction().Session(s.clientSession).ClusterClock(s.client.clock).Database("admin"). - Deployment(s.deployment).WriteConcern(s.clientSession.CurrentWc).ServerSelector(selector). - Retry(driver.RetryOncePerCommand).CommandMonitor(s.client.monitor). - RecoveryToken(bsoncore.Document(s.clientSession.RecoveryToken)).ServerAPI(s.client.serverAPI).Execute(ctx) + + retry := driver.RetryOncePerCommand + op := &operation.AbortTransaction{ + Session: s.clientSession, + Clock: s.client.clock, + Deployment: s.deployment, + WriteConcern: s.clientSession.CurrentWc, + Selector: selector, + Retry: &retry, + Monitor: s.client.monitor, + RecoveryToken: bsoncore.Document(s.clientSession.RecoveryToken), + ServerAPI: s.client.serverAPI, + } + _ = op.Execute(ctx) s.clientSession.Aborting = false _ = s.clientSession.AbortTransaction() @@ -324,11 +334,18 @@ func (s *sessionImpl) CommitTransaction(ctx context.Context) error { selector := makePinnedSelector(s.clientSession, description.WriteSelector()) s.clientSession.Committing = true - op := operation.NewCommitTransaction(). - Session(s.clientSession).ClusterClock(s.client.clock).Database("admin").Deployment(s.deployment). - WriteConcern(s.clientSession.CurrentWc).ServerSelector(selector).Retry(driver.RetryOncePerCommand). - CommandMonitor(s.client.monitor).RecoveryToken(bsoncore.Document(s.clientSession.RecoveryToken)). - ServerAPI(s.client.serverAPI).MaxTime(s.clientSession.CurrentMct) + + retry := driver.RetryOncePerCommand + op := &operation.CommitTransaction{ + Session: s.clientSession, + Clock: s.client.clock, + Deployment: s.deployment, + WriteConcern: s.clientSession.CurrentWc, + Selector: selector, + Retry: &retry, + ServerAPI: s.client.serverAPI, + MaxTime: s.clientSession.CurrentMct, + } err = op.Execute(ctx) // Return error without updating transaction state if it is a timeout, as the transaction has not diff --git a/x/mongo/driver/operation/abort_transaction.go b/x/mongo/driver/operation/abort_transaction.go index 9413727130..3777081880 100644 --- a/x/mongo/driver/operation/abort_transaction.go +++ b/x/mongo/driver/operation/abort_transaction.go @@ -21,23 +21,38 @@ import ( // AbortTransaction performs an abortTransaction operation. type AbortTransaction struct { - recoveryToken bsoncore.Document - session *session.Client - clock *session.ClusterClock - collection string - monitor *event.CommandMonitor - crypt driver.Crypt - database string - deployment driver.Deployment - selector description.ServerSelector - writeConcern *writeconcern.WriteConcern - retry *driver.RetryMode - serverAPI *driver.ServerAPIOptions -} + // RecoveryToken is the recovery token to use when committing or aborting a + // sharded transaction. + RecoveryToken bsoncore.Document + + // Session is the session for this operation. + Session *session.Client + + // Clock is the cluster clock for this operation. + Clock *session.ClusterClock + + // Monitor is the monitor to use for APM events. + Monitor *event.CommandMonitor + + // Crypt is the Crypt object to use for automatic encryption and decryption. + Crypt driver.Crypt + + // Deployment is the deployment to use for this operation. + Deployment driver.Deployment + + // Selector is the selector used to retrieve a server. + Selector description.ServerSelector + + // WriteConcern is the write concern for this operation. + WriteConcern *writeconcern.WriteConcern -// NewAbortTransaction constructs and returns a new AbortTransaction. -func NewAbortTransaction() *AbortTransaction { - return &AbortTransaction{} + // Retry enables retryable mode for this operation. Retries are handled + // automatically in driver.Operation.Execute based on how the operation is + // set. + Retry *driver.RetryMode + + // ServerAPI is the server API version for this operation. + ServerAPI *driver.ServerAPIOptions } func (at *AbortTransaction) processResponse(driver.ResponseInfo) error { @@ -47,155 +62,33 @@ func (at *AbortTransaction) processResponse(driver.ResponseInfo) error { // Execute runs this operations and returns an error if the operation did not execute successfully. func (at *AbortTransaction) Execute(ctx context.Context) error { - if at.deployment == nil { + if at.Deployment == nil { return errors.New("the AbortTransaction operation must have a Deployment set before Execute can be called") } return driver.Operation{ CommandFn: at.command, ProcessResponseFn: at.processResponse, - RetryMode: at.retry, + RetryMode: at.Retry, Type: driver.Write, - Client: at.session, - Clock: at.clock, - CommandMonitor: at.monitor, - Crypt: at.crypt, - Database: at.database, - Deployment: at.deployment, - Selector: at.selector, - WriteConcern: at.writeConcern, - ServerAPI: at.serverAPI, + Client: at.Session, + Clock: at.Clock, + CommandMonitor: at.Monitor, + Crypt: at.Crypt, + Database: "admin", + Deployment: at.Deployment, + Selector: at.Selector, + WriteConcern: at.WriteConcern, + ServerAPI: at.ServerAPI, Name: driverutil.AbortTransactionOp, }.Execute(ctx) } func (at *AbortTransaction) command(dst []byte, _ description.SelectedServer) ([]byte, error) { - dst = bsoncore.AppendInt32Element(dst, "abortTransaction", 1) - if at.recoveryToken != nil { - dst = bsoncore.AppendDocumentElement(dst, "recoveryToken", at.recoveryToken) + if at.RecoveryToken != nil { + dst = bsoncore.AppendDocumentElement(dst, "recoveryToken", at.RecoveryToken) } return dst, nil } - -// RecoveryToken sets the recovery token to use when committing or aborting a sharded transaction. -func (at *AbortTransaction) RecoveryToken(recoveryToken bsoncore.Document) *AbortTransaction { - if at == nil { - at = new(AbortTransaction) - } - - at.recoveryToken = recoveryToken - return at -} - -// Session sets the session for this operation. -func (at *AbortTransaction) Session(session *session.Client) *AbortTransaction { - if at == nil { - at = new(AbortTransaction) - } - - at.session = session - return at -} - -// ClusterClock sets the cluster clock for this operation. -func (at *AbortTransaction) ClusterClock(clock *session.ClusterClock) *AbortTransaction { - if at == nil { - at = new(AbortTransaction) - } - - at.clock = clock - return at -} - -// Collection sets the collection that this command will run against. -func (at *AbortTransaction) Collection(collection string) *AbortTransaction { - if at == nil { - at = new(AbortTransaction) - } - - at.collection = collection - return at -} - -// CommandMonitor sets the monitor to use for APM events. -func (at *AbortTransaction) CommandMonitor(monitor *event.CommandMonitor) *AbortTransaction { - if at == nil { - at = new(AbortTransaction) - } - - at.monitor = monitor - return at -} - -// Crypt sets the Crypt object to use for automatic encryption and decryption. -func (at *AbortTransaction) Crypt(crypt driver.Crypt) *AbortTransaction { - if at == nil { - at = new(AbortTransaction) - } - - at.crypt = crypt - return at -} - -// Database sets the database to run this operation against. -func (at *AbortTransaction) Database(database string) *AbortTransaction { - if at == nil { - at = new(AbortTransaction) - } - - at.database = database - return at -} - -// Deployment sets the deployment to use for this operation. -func (at *AbortTransaction) Deployment(deployment driver.Deployment) *AbortTransaction { - if at == nil { - at = new(AbortTransaction) - } - - at.deployment = deployment - return at -} - -// ServerSelector sets the selector used to retrieve a server. -func (at *AbortTransaction) ServerSelector(selector description.ServerSelector) *AbortTransaction { - if at == nil { - at = new(AbortTransaction) - } - - at.selector = selector - return at -} - -// WriteConcern sets the write concern for this operation. -func (at *AbortTransaction) WriteConcern(writeConcern *writeconcern.WriteConcern) *AbortTransaction { - if at == nil { - at = new(AbortTransaction) - } - - at.writeConcern = writeConcern - return at -} - -// Retry enables retryable mode for this operation. Retries are handled automatically in driver.Operation.Execute based -// on how the operation is set. -func (at *AbortTransaction) Retry(retry driver.RetryMode) *AbortTransaction { - if at == nil { - at = new(AbortTransaction) - } - - at.retry = &retry - return at -} - -// ServerAPI sets the server API version for this operation. -func (at *AbortTransaction) ServerAPI(serverAPI *driver.ServerAPIOptions) *AbortTransaction { - if at == nil { - at = new(AbortTransaction) - } - - at.serverAPI = serverAPI - return at -} diff --git a/x/mongo/driver/operation/commit_transaction.go b/x/mongo/driver/operation/commit_transaction.go index 11c6f69ddf..b66abdc41d 100644 --- a/x/mongo/driver/operation/commit_transaction.go +++ b/x/mongo/driver/operation/commit_transaction.go @@ -22,23 +22,42 @@ import ( // CommitTransaction attempts to commit a transaction. type CommitTransaction struct { - maxTime *time.Duration - recoveryToken bsoncore.Document - session *session.Client - clock *session.ClusterClock - monitor *event.CommandMonitor - crypt driver.Crypt - database string - deployment driver.Deployment - selector description.ServerSelector - writeConcern *writeconcern.WriteConcern - retry *driver.RetryMode - serverAPI *driver.ServerAPIOptions -} + // MaxTime is the maximum amount of time to allow the query to run on the + // server. + MaxTime *time.Duration + + // RecoveryToken is the recovery token to use when committing or aborting a + // sharded transaction. + RecoveryToken bsoncore.Document + + // Session is the session for this operation. + Session *session.Client + + // Clock is the cluster clock for this operation. + Clock *session.ClusterClock + + // Monitor is the monitor to use for APM events. + Monitor *event.CommandMonitor + + // Crypt is the Crypt object to use for automatic encryption and decryption. + Crypt driver.Crypt + + // Deployment is the deployment to use for this operation. + Deployment driver.Deployment + + // Selector is the selector used to retrieve a server. + Selector description.ServerSelector -// NewCommitTransaction constructs and returns a new CommitTransaction. -func NewCommitTransaction() *CommitTransaction { - return &CommitTransaction{} + // WriteConcern is the write concern for this operation. + WriteConcern *writeconcern.WriteConcern + + // Retry enables retryable mode for this operation. Retries are handled + // automatically in driver.Operation.Execute based on how the operation is + // set. + Retry *driver.RetryMode + + // ServerAPI is the server API version for this operation. + ServerAPI *driver.ServerAPIOptions } func (ct *CommitTransaction) processResponse(driver.ResponseInfo) error { @@ -48,156 +67,34 @@ func (ct *CommitTransaction) processResponse(driver.ResponseInfo) error { // Execute runs this operations and returns an error if the operation did not execute successfully. func (ct *CommitTransaction) Execute(ctx context.Context) error { - if ct.deployment == nil { + if ct.Deployment == nil { return errors.New("the CommitTransaction operation must have a Deployment set before Execute can be called") } return driver.Operation{ CommandFn: ct.command, ProcessResponseFn: ct.processResponse, - RetryMode: ct.retry, + RetryMode: ct.Retry, Type: driver.Write, - Client: ct.session, - Clock: ct.clock, - CommandMonitor: ct.monitor, - Crypt: ct.crypt, - Database: ct.database, - Deployment: ct.deployment, - MaxTime: ct.maxTime, - Selector: ct.selector, - WriteConcern: ct.writeConcern, - ServerAPI: ct.serverAPI, + Client: ct.Session, + Clock: ct.Clock, + CommandMonitor: ct.Monitor, + Crypt: ct.Crypt, + Database: "admin", + Deployment: ct.Deployment, + MaxTime: ct.MaxTime, + Selector: ct.Selector, + WriteConcern: ct.WriteConcern, + ServerAPI: ct.ServerAPI, Name: driverutil.CommitTransactionOp, }.Execute(ctx) } func (ct *CommitTransaction) command(dst []byte, _ description.SelectedServer) ([]byte, error) { - dst = bsoncore.AppendInt32Element(dst, "commitTransaction", 1) - if ct.recoveryToken != nil { - dst = bsoncore.AppendDocumentElement(dst, "recoveryToken", ct.recoveryToken) + if ct.RecoveryToken != nil { + dst = bsoncore.AppendDocumentElement(dst, "recoveryToken", ct.RecoveryToken) } return dst, nil } - -// MaxTime specifies the maximum amount of time to allow the query to run on the server. -func (ct *CommitTransaction) MaxTime(maxTime *time.Duration) *CommitTransaction { - if ct == nil { - ct = new(CommitTransaction) - } - - ct.maxTime = maxTime - return ct -} - -// RecoveryToken sets the recovery token to use when committing or aborting a sharded transaction. -func (ct *CommitTransaction) RecoveryToken(recoveryToken bsoncore.Document) *CommitTransaction { - if ct == nil { - ct = new(CommitTransaction) - } - - ct.recoveryToken = recoveryToken - return ct -} - -// Session sets the session for this operation. -func (ct *CommitTransaction) Session(session *session.Client) *CommitTransaction { - if ct == nil { - ct = new(CommitTransaction) - } - - ct.session = session - return ct -} - -// ClusterClock sets the cluster clock for this operation. -func (ct *CommitTransaction) ClusterClock(clock *session.ClusterClock) *CommitTransaction { - if ct == nil { - ct = new(CommitTransaction) - } - - ct.clock = clock - return ct -} - -// CommandMonitor sets the monitor to use for APM events. -func (ct *CommitTransaction) CommandMonitor(monitor *event.CommandMonitor) *CommitTransaction { - if ct == nil { - ct = new(CommitTransaction) - } - - ct.monitor = monitor - return ct -} - -// Crypt sets the Crypt object to use for automatic encryption and decryption. -func (ct *CommitTransaction) Crypt(crypt driver.Crypt) *CommitTransaction { - if ct == nil { - ct = new(CommitTransaction) - } - - ct.crypt = crypt - return ct -} - -// Database sets the database to run this operation against. -func (ct *CommitTransaction) Database(database string) *CommitTransaction { - if ct == nil { - ct = new(CommitTransaction) - } - - ct.database = database - return ct -} - -// Deployment sets the deployment to use for this operation. -func (ct *CommitTransaction) Deployment(deployment driver.Deployment) *CommitTransaction { - if ct == nil { - ct = new(CommitTransaction) - } - - ct.deployment = deployment - return ct -} - -// ServerSelector sets the selector used to retrieve a server. -func (ct *CommitTransaction) ServerSelector(selector description.ServerSelector) *CommitTransaction { - if ct == nil { - ct = new(CommitTransaction) - } - - ct.selector = selector - return ct -} - -// WriteConcern sets the write concern for this operation. -func (ct *CommitTransaction) WriteConcern(writeConcern *writeconcern.WriteConcern) *CommitTransaction { - if ct == nil { - ct = new(CommitTransaction) - } - - ct.writeConcern = writeConcern - return ct -} - -// Retry enables retryable mode for this operation. Retries are handled automatically in driver.Operation.Execute based -// on how the operation is set. -func (ct *CommitTransaction) Retry(retry driver.RetryMode) *CommitTransaction { - if ct == nil { - ct = new(CommitTransaction) - } - - ct.retry = &retry - return ct -} - -// ServerAPI sets the server API version for this operation. -func (ct *CommitTransaction) ServerAPI(serverAPI *driver.ServerAPIOptions) *CommitTransaction { - if ct == nil { - ct = new(CommitTransaction) - } - - ct.serverAPI = serverAPI - return ct -}