Skip to content

Commit 4352427

Browse files
Move unsafe bool to findOne
1 parent 5874968 commit 4352427

File tree

5 files changed

+155
-124
lines changed

5 files changed

+155
-124
lines changed

mongo/collection.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,13 +1215,14 @@ func (coll *Collection) Find(ctx context.Context, filter interface{},
12151215
//
12161216
// See DRIVERS-2722 for more detail.
12171217
_, deadlineSet := ctx.Deadline()
1218-
return coll.find(ctx, filter, deadlineSet, opts...)
1218+
return coll.find(ctx, filter, deadlineSet, false, opts...)
12191219
}
12201220

12211221
func (coll *Collection) find(
12221222
ctx context.Context,
12231223
filter interface{},
12241224
omitCSOTMaxTimeMS bool,
1225+
unsafeAllowSeperateMaxTimeMS bool,
12251226
opts ...*options.FindOptions,
12261227
) (cur *Cursor, err error) {
12271228

@@ -1260,7 +1261,8 @@ func (coll *Collection) find(
12601261
ClusterClock(coll.client.clock).Database(coll.db.name).Collection(coll.name).
12611262
Deployment(coll.client.deployment).Crypt(coll.client.cryptFLE).ServerAPI(coll.client.serverAPI).
12621263
Timeout(coll.client.timeout).MaxTime(fo.MaxTime).Logger(coll.client.logger).
1263-
OmitCSOTMaxTimeMS(omitCSOTMaxTimeMS).Authenticator(coll.client.authenticator)
1264+
OmitCSOTMaxTimeMS(omitCSOTMaxTimeMS).Authenticator(coll.client.authenticator).
1265+
UnsafeAllowSeperateMaxTimeMS(unsafeAllowSeperateMaxTimeMS)
12641266

12651267
cursorOpts := coll.client.createBaseCursorOptions()
12661268

@@ -1408,6 +1410,7 @@ func (coll *Collection) FindOne(ctx context.Context, filter interface{},
14081410
ctx = context.Background()
14091411
}
14101412

1413+
var unsafeAllowSeperateMaxTimeMS bool
14111414
findOpts := make([]*options.FindOptions, 0, len(opts))
14121415
for _, opt := range opts {
14131416
if opt == nil {
@@ -1433,12 +1436,16 @@ func (coll *Collection) FindOne(ctx context.Context, filter interface{},
14331436
Snapshot: opt.Snapshot,
14341437
Sort: opt.Sort,
14351438
})
1439+
1440+
if opt.UnsafeAllowSeperateMaxTimeMS {
1441+
unsafeAllowSeperateMaxTimeMS = opt.UnsafeAllowSeperateMaxTimeMS
1442+
}
14361443
}
14371444
// Unconditionally send a limit to make sure only one document is returned and the cursor is not kept open
14381445
// by the server.
14391446
findOpts = append(findOpts, options.Find().SetLimit(-1))
14401447

1441-
cursor, err := coll.find(ctx, filter, false, findOpts...)
1448+
cursor, err := coll.find(ctx, filter, false, unsafeAllowSeperateMaxTimeMS, findOpts...)
14421449
return &SingleResult{
14431450
ctx: ctx,
14441451
cur: cursor,

mongo/integration/csot_test.go

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ func TestCSOT_maxTimeMS(t *testing.T) {
608608
commandName: "find",
609609
fn: func(ctx context.Context, coll *mongo.Collection, maxTime *time.Duration) error {
610610
opts := options.FindOne()
611+
opts.UnsafeAllowSeperateMaxTimeMS = true
611612
if maxTime != nil {
612613
opts.SetMaxTime(*maxTime)
613614
}
@@ -616,45 +617,45 @@ func TestCSOT_maxTimeMS(t *testing.T) {
616617
},
617618
cursorOp: false,
618619
},
619-
{
620-
name: "Find",
621-
commandName: "find",
622-
fn: func(ctx context.Context, coll *mongo.Collection, maxTime *time.Duration) error {
623-
opts := options.Find()
624-
if maxTime != nil {
625-
opts.SetMaxTime(*maxTime)
626-
}
627-
_, err := coll.Find(ctx, bson.D{}, opts)
628-
return err
629-
},
630-
cursorOp: true,
631-
},
632-
{
633-
name: "FindOneAndUpdate",
634-
commandName: "findAndModify",
635-
fn: func(ctx context.Context, coll *mongo.Collection, maxTime *time.Duration) error {
636-
opts := options.FindOneAndUpdate()
637-
if maxTime != nil {
638-
opts.SetMaxTime(*maxTime)
639-
}
640-
res := coll.FindOneAndUpdate(ctx, bson.D{}, bson.M{"$set": bson.M{"key": "value"}}, opts)
641-
return res.Err()
642-
},
643-
cursorOp: false,
644-
},
645-
{
646-
name: "Aggregate",
647-
commandName: "aggregate",
648-
fn: func(ctx context.Context, coll *mongo.Collection, maxTime *time.Duration) error {
649-
opts := options.Aggregate()
650-
if maxTime != nil {
651-
opts.SetMaxTime(*maxTime)
652-
}
653-
_, err := coll.Aggregate(ctx, bson.D{}, opts)
654-
return err
655-
},
656-
cursorOp: true,
657-
},
620+
//{
621+
// name: "Find",
622+
// commandName: "find",
623+
// fn: func(ctx context.Context, coll *mongo.Collection, maxTime *time.Duration) error {
624+
// opts := options.Find()
625+
// if maxTime != nil {
626+
// opts.SetMaxTime(*maxTime)
627+
// }
628+
// _, err := coll.Find(ctx, bson.D{}, opts)
629+
// return err
630+
// },
631+
// cursorOp: true,
632+
// },
633+
//{
634+
// name: "FindOneAndUpdate",
635+
// commandName: "findAndModify",
636+
// fn: func(ctx context.Context, coll *mongo.Collection, maxTime *time.Duration) error {
637+
// opts := options.FindOneAndUpdate()
638+
// if maxTime != nil {
639+
// opts.SetMaxTime(*maxTime)
640+
// }
641+
// res := coll.FindOneAndUpdate(ctx, bson.D{}, bson.M{"$set": bson.M{"key": "value"}}, opts)
642+
// return res.Err()
643+
// },
644+
// cursorOp: false,
645+
// },
646+
//{
647+
// name: "Aggregate",
648+
// commandName: "aggregate",
649+
// fn: func(ctx context.Context, coll *mongo.Collection, maxTime *time.Duration) error {
650+
// opts := options.Aggregate()
651+
// if maxTime != nil {
652+
// opts.SetMaxTime(*maxTime)
653+
// }
654+
// _, err := coll.Aggregate(ctx, bson.D{}, opts)
655+
// return err
656+
// },
657+
// cursorOp: true,
658+
// },
658659
}
659660

660661
for _, op := range ops {
@@ -698,8 +699,8 @@ func TestCSOT_maxTimeMS(t *testing.T) {
698699

699700
for _, tc := range testCases {
700701
mt.Run(tc.name, func(mt *mtest.T) {
701-
driver.UnsafeAllowSeperateMaxTimeMSWithCSOT = true
702-
defer func() { driver.UnsafeAllowSeperateMaxTimeMSWithCSOT = false }()
702+
// driver.UnsafeAllowSeperateMaxTimeMSWithCSOT = true
703+
// defer func() { driver.UnsafeAllowSeperateMaxTimeMSWithCSOT = false }()
703704

704705
// Enable CSOT
705706
mt.ResetClient(options.Client().SetTimeout(15 * time.Second))
@@ -738,7 +739,6 @@ func TestCSOT_maxTimeMS(t *testing.T) {
738739
})
739740
}
740741
})
741-
742742
}
743743

744744
func TestCSOT_errors(t *testing.T) {

mongo/options/findoptions.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,19 @@ type FindOneOptions struct {
418418
// A document specifying the sort order to apply to the query. The first document in the sorted order will be
419419
// returned. The driver will return an error if the sort parameter is a multi-key map.
420420
Sort interface{}
421+
422+
// UnsafeAllowSeperateMaxTimeMS is allows setting maxTimeMS independently of
423+
// the context deadline when CSOT is enabled (client.Timeout >=0). If a user
424+
// provides a context deadline it will be used for all blocking client-side
425+
// logic (e.g. socket timeouts, checking out connections, etc).
426+
//
427+
// This switch is untested and experimental.
428+
//
429+
// ⚠️ **USE WITH CAUTION** ⚠️
430+
//
431+
// Deprecated: This option is for internal use only and should not be set. It
432+
// may be changed or removed in any release.
433+
UnsafeAllowSeperateMaxTimeMS bool
421434
}
422435

423436
// FindOne creates a new FindOneOptions instance.
@@ -615,6 +628,9 @@ func MergeFindOneOptions(opts ...*FindOneOptions) *FindOneOptions {
615628
if opt.Sort != nil {
616629
fo.Sort = opt.Sort
617630
}
631+
if opt.UnsafeAllowSeperateMaxTimeMS {
632+
fo.UnsafeAllowSeperateMaxTimeMS = opt.UnsafeAllowSeperateMaxTimeMS
633+
}
618634
}
619635

620636
return fo

x/mongo/driver/operation.go

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,23 +60,6 @@ const (
6060
readSnapshotMinWireVersion int32 = 13
6161
)
6262

63-
// UnsafeAllowSeperateMaxTimeMSWithCSOT is a global flag that allows users to
64-
// set maxTimeMS independently of the context deadline when CSOT is enabled
65-
// (client.Timeout >=0). If a user provides a context deadline it will be used
66-
// for all blocking client-side logic (e.g. socket timeouts, checking out
67-
// connections, etc).
68-
//
69-
// This switch is untested and experimental.
70-
//
71-
// ⚠️ **USE WITH CAUTION** ⚠️
72-
//
73-
// The CSOT default behavior is for the Go Driver to derive maxTimeMS from the
74-
// context deadline to ensure that the server-side timeout aligns with the
75-
// client-side operation timeout.
76-
//
77-
// THIS OPTION MAY BE REMOVED AT ANY TIME.
78-
var UnsafeAllowSeperateMaxTimeMSWithCSOT bool
79-
8063
// RetryablePoolError is a connection pool error that can be retried while executing an operation.
8164
type RetryablePoolError interface {
8265
Retryable() bool
@@ -341,6 +324,19 @@ type Operation struct {
341324
// where a default read preference is used when the operation
342325
// ReadPreference is not specified.
343326
omitReadPreference bool
327+
328+
// UnsafeAllowSeperateMaxTimeMS is allows setting maxTimeMS independently of
329+
// the context deadline when CSOT is enabled (client.Timeout >=0). If a user
330+
// provides a context deadline it will be used for all blocking client-side
331+
// logic (e.g. socket timeouts, checking out connections, etc).
332+
//
333+
// This switch is untested and experimental.
334+
//
335+
// ⚠️ **USE WITH CAUTION** ⚠️
336+
//
337+
// Deprecated: This option is for internal use only and should not be set. It
338+
// may be changed or removed in any release.
339+
UnsafeAllowSeperateMaxTimeMS bool
344340
}
345341

346342
// shouldEncrypt returns true if this operation should automatically be encrypted.
@@ -1610,7 +1606,7 @@ func (op Operation) addClusterTime(dst []byte, desc description.SelectedServer)
16101606
// operation's MaxTimeMS if set. If no MaxTimeMS is set on the operation, and context is
16111607
// not a Timeout context, calculateMaxTimeMS returns 0.
16121608
func (op Operation) calculateMaxTimeMS(ctx context.Context, mon RTTMonitor) (uint64, error) {
1613-
unsafelyOverrideCSOT := UnsafeAllowSeperateMaxTimeMSWithCSOT && op.MaxTime != nil
1609+
unsafelyOverrideCSOT := op.UnsafeAllowSeperateMaxTimeMS && op.MaxTime != nil
16141610

16151611
// If CSOT is enabled and we're not omitting the CSOT-calculated maxTimeMS
16161612
// value, then calculate maxTimeMS.

x/mongo/driver/operation/find.go

Lines changed: 73 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -25,46 +25,47 @@ import (
2525

2626
// Find performs a find operation.
2727
type Find struct {
28-
authenticator driver.Authenticator
29-
allowDiskUse *bool
30-
allowPartialResults *bool
31-
awaitData *bool
32-
batchSize *int32
33-
collation bsoncore.Document
34-
comment *string
35-
filter bsoncore.Document
36-
hint bsoncore.Value
37-
let bsoncore.Document
38-
limit *int64
39-
max bsoncore.Document
40-
maxTime *time.Duration
41-
min bsoncore.Document
42-
noCursorTimeout *bool
43-
oplogReplay *bool
44-
projection bsoncore.Document
45-
returnKey *bool
46-
showRecordID *bool
47-
singleBatch *bool
48-
skip *int64
49-
snapshot *bool
50-
sort bsoncore.Document
51-
tailable *bool
52-
session *session.Client
53-
clock *session.ClusterClock
54-
collection string
55-
monitor *event.CommandMonitor
56-
crypt driver.Crypt
57-
database string
58-
deployment driver.Deployment
59-
readConcern *readconcern.ReadConcern
60-
readPreference *readpref.ReadPref
61-
selector description.ServerSelector
62-
retry *driver.RetryMode
63-
result driver.CursorResponse
64-
serverAPI *driver.ServerAPIOptions
65-
timeout *time.Duration
66-
omitCSOTMaxTimeMS bool
67-
logger *logger.Logger
28+
authenticator driver.Authenticator
29+
allowDiskUse *bool
30+
allowPartialResults *bool
31+
awaitData *bool
32+
batchSize *int32
33+
collation bsoncore.Document
34+
comment *string
35+
filter bsoncore.Document
36+
hint bsoncore.Value
37+
let bsoncore.Document
38+
limit *int64
39+
max bsoncore.Document
40+
maxTime *time.Duration
41+
min bsoncore.Document
42+
noCursorTimeout *bool
43+
oplogReplay *bool
44+
projection bsoncore.Document
45+
returnKey *bool
46+
showRecordID *bool
47+
singleBatch *bool
48+
skip *int64
49+
snapshot *bool
50+
sort bsoncore.Document
51+
tailable *bool
52+
session *session.Client
53+
clock *session.ClusterClock
54+
collection string
55+
monitor *event.CommandMonitor
56+
crypt driver.Crypt
57+
database string
58+
deployment driver.Deployment
59+
readConcern *readconcern.ReadConcern
60+
readPreference *readpref.ReadPref
61+
selector description.ServerSelector
62+
retry *driver.RetryMode
63+
result driver.CursorResponse
64+
serverAPI *driver.ServerAPIOptions
65+
timeout *time.Duration
66+
omitCSOTMaxTimeMS bool
67+
logger *logger.Logger
68+
unsafeAllowSeperateMaxTimeMS bool
6869
}
6970

7071
// NewFind constructs and returns a new Find.
@@ -93,27 +94,28 @@ func (f *Find) Execute(ctx context.Context) error {
9394
}
9495

9596
return driver.Operation{
96-
CommandFn: f.command,
97-
ProcessResponseFn: f.processResponse,
98-
RetryMode: f.retry,
99-
Type: driver.Read,
100-
Client: f.session,
101-
Clock: f.clock,
102-
CommandMonitor: f.monitor,
103-
Crypt: f.crypt,
104-
Database: f.database,
105-
Deployment: f.deployment,
106-
MaxTime: f.maxTime,
107-
ReadConcern: f.readConcern,
108-
ReadPreference: f.readPreference,
109-
Selector: f.selector,
110-
Legacy: driver.LegacyFind,
111-
ServerAPI: f.serverAPI,
112-
Timeout: f.timeout,
113-
Logger: f.logger,
114-
Name: driverutil.FindOp,
115-
OmitCSOTMaxTimeMS: f.omitCSOTMaxTimeMS,
116-
Authenticator: f.authenticator,
97+
CommandFn: f.command,
98+
ProcessResponseFn: f.processResponse,
99+
RetryMode: f.retry,
100+
Type: driver.Read,
101+
Client: f.session,
102+
Clock: f.clock,
103+
CommandMonitor: f.monitor,
104+
Crypt: f.crypt,
105+
Database: f.database,
106+
Deployment: f.deployment,
107+
MaxTime: f.maxTime,
108+
ReadConcern: f.readConcern,
109+
ReadPreference: f.readPreference,
110+
Selector: f.selector,
111+
Legacy: driver.LegacyFind,
112+
ServerAPI: f.serverAPI,
113+
Timeout: f.timeout,
114+
Logger: f.logger,
115+
Name: driverutil.FindOp,
116+
OmitCSOTMaxTimeMS: f.omitCSOTMaxTimeMS,
117+
Authenticator: f.authenticator,
118+
UnsafeAllowSeperateMaxTimeMS: f.unsafeAllowSeperateMaxTimeMS,
117119
}.Execute(ctx)
118120

119121
}
@@ -587,3 +589,13 @@ func (f *Find) Authenticator(authenticator driver.Authenticator) *Find {
587589
f.authenticator = authenticator
588590
return f
589591
}
592+
593+
// UnsafeAllowSeperateMaxTimeMS allows CSOT with independent maxTimeMS.
594+
func (f *Find) UnsafeAllowSeperateMaxTimeMS(val bool) *Find {
595+
if f == nil {
596+
f = new(Find)
597+
}
598+
599+
f.unsafeAllowSeperateMaxTimeMS = val
600+
return f
601+
}

0 commit comments

Comments
 (0)