Skip to content

Commit

Permalink
GODRIVER-2348 Do not set transactional wtimeout
Browse files Browse the repository at this point in the history
  • Loading branch information
prestonvasquez committed Mar 19, 2024
1 parent 058b343 commit 00fb9da
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 39 deletions.
46 changes: 17 additions & 29 deletions x/mongo/driver/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,6 @@ func (op Operation) addBatchArray(dst []byte) []byte {
}

func (op Operation) createLegacyHandshakeWireMessage(
ctx context.Context,
maxTimeMS uint64,
dst []byte,
desc description.SelectedServer,
Expand Down Expand Up @@ -1217,7 +1216,7 @@ func (op Operation) createLegacyHandshakeWireMessage(
return dst, info, err
}

dst, err = op.addWriteConcern(ctx, dst, desc)
dst, err = op.addWriteConcern(dst, desc)
if err != nil {
return dst, info, err
}
Expand Down Expand Up @@ -1289,7 +1288,7 @@ func (op Operation) createMsgWireMessage(
if err != nil {
return dst, info, err
}
dst, err = op.addWriteConcern(ctx, dst, desc)
dst, err = op.addWriteConcern(dst, desc)
if err != nil {
return dst, info, err
}
Expand Down Expand Up @@ -1356,7 +1355,7 @@ func (op Operation) createWireMessage(
requestID int32,
) ([]byte, startedInformation, error) {
if isLegacyHandshake(op, desc) {
return op.createLegacyHandshakeWireMessage(ctx, maxTimeMS, dst, desc)
return op.createLegacyHandshakeWireMessage(maxTimeMS, dst, desc)
}

return op.createMsgWireMessage(ctx, maxTimeMS, dst, desc, conn, requestID)
Expand Down Expand Up @@ -1464,23 +1463,7 @@ func (op Operation) addReadConcern(dst []byte, desc description.SelectedServer)
return bsoncore.AppendDocumentElement(dst, "readConcern", data), nil
}

func getWriteConcernTimeout(ctx context.Context, op Operation) time.Duration {
if contextDeadline, ok := ctx.Deadline(); ok {
return time.Until(contextDeadline)
}

if op.Timeout != nil {
return *op.Timeout
}

if op.Client == nil {
return 0
}

return op.Client.CurrentWTimeout
}

func marshalBSONWriteConcern(wc writeconcern.WriteConcern, wtimeout time.Duration) (bsontype.Type, []byte, error) {
func marshalBSONWriteConcern(wc writeconcern.WriteConcern) (bsontype.Type, []byte, error) {
var elems []byte
if wc.W != nil {
// Only support string or int values for W. That aligns with the
Expand Down Expand Up @@ -1511,18 +1494,14 @@ func marshalBSONWriteConcern(wc writeconcern.WriteConcern, wtimeout time.Duratio
elems = bsoncore.AppendBooleanElement(elems, "j", *wc.Journal)
}

if wtimeout != 0 {
elems = bsoncore.AppendInt64Element(elems, "wtimeout", int64(wtimeout/time.Millisecond))
}

if len(elems) == 0 {
return 0, nil, errEmptyWriteConcern
}

return bson.TypeEmbeddedDocument, bsoncore.BuildDocument(nil, elems), nil
}

func (op Operation) addWriteConcern(ctx context.Context, dst []byte, desc description.SelectedServer) ([]byte, error) {
func (op Operation) addWriteConcern(dst []byte, desc description.SelectedServer) ([]byte, error) {
if op.MinimumWriteConcernWireVersion > 0 && (desc.WireVersion == nil || !desc.WireVersion.Includes(op.MinimumWriteConcernWireVersion)) {
return dst, nil
}
Expand All @@ -1531,9 +1510,18 @@ func (op Operation) addWriteConcern(ctx context.Context, dst []byte, desc descri
return dst, nil
}

wtimeout := getWriteConcernTimeout(ctx, op)

typ, wcBSON, err := marshalBSONWriteConcern(*wc, wtimeout)
// The specifications for committing a transaction states:
//
// > if the modified write concern does not include a wtimeout value, drivers
// > MUST also apply wtimeout: 10000 to the write concern in order to avoid
// > waiting forever (or until a socket timeout) if the majority write concern
// > cannot be satisfied.
//
// However, since the Go Driver now supports client and operation-level CSOT,
// there is a way for a user to ensure that operations never wait forever.
// Therefore, the Go Driver team has opted to implement this spec
// requirement.
typ, wcBSON, err := marshalBSONWriteConcern(*wc)
if errors.Is(err, errEmptyWriteConcern) {
return dst, nil
}
Expand Down
12 changes: 2 additions & 10 deletions x/mongo/driver/operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ func TestOperation(t *testing.T) {
want := bsoncore.AppendDocumentElement(nil, "writeConcern", bsoncore.BuildDocumentFromElements(
nil, bsoncore.AppendStringElement(nil, "w", "majority"),
))
got, err := Operation{WriteConcern: writeconcern.Majority()}.addWriteConcern(context.Background(), nil, description.SelectedServer{})
got, err := Operation{WriteConcern: writeconcern.Majority()}.addWriteConcern(nil, description.SelectedServer{})
noerr(t, err)
if !bytes.Equal(got, want) {
t.Errorf("WriteConcern elements do not match. got %v; want %v", got, want)
Expand Down Expand Up @@ -978,14 +978,6 @@ func TestMarshalBSONWriteConcern(t *testing.T) {
wtimeout: 0,
wantErr: "a write concern must have at least one field set",
},
{
name: "journal and wtimout",
writeConcern: *writeconcern.Journaled(),
wtimeout: 10 * time.Millisecond,
wantBSONType: bson.TypeEmbeddedDocument,
want: bson.D{{"j", true}, {"wtimeout", int64(10 * time.Millisecond / time.Millisecond)}},
wantErr: "a write concern must have at least one field set",
},
}

for _, test := range tests {
Expand All @@ -994,7 +986,7 @@ func TestMarshalBSONWriteConcern(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
t.Parallel()

gotBSONType, gotBSON, gotErr := marshalBSONWriteConcern(test.writeConcern, test.wtimeout)
gotBSONType, gotBSON, gotErr := marshalBSONWriteConcern(test.writeConcern)
assert.Equal(t, test.wantBSONType, gotBSONType)

wantBSON := []byte(nil)
Expand Down

0 comments on commit 00fb9da

Please sign in to comment.