Skip to content

Commit 6bd6a19

Browse files
vbabaninkatcharov
andauthored
Adjust maxAwaitTimeMS by remaining timeout. (#1650)
JAVA-5720 --------- Co-authored-by: Maxim Katcharov <[email protected]>
1 parent 7e1f927 commit 6bd6a19

File tree

3 files changed

+166
-3
lines changed

3 files changed

+166
-3
lines changed

driver-core/src/main/com/mongodb/internal/TimeoutContext.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,10 @@ public long getMaxAwaitTimeMS() {
192192

193193
public void runMaxTimeMS(final LongConsumer onRemaining) {
194194
if (maxTimeSupplier != null) {
195-
runWithFixedTimeout(maxTimeSupplier.get(), onRemaining);
195+
long maxTimeMS = maxTimeSupplier.get();
196+
if (maxTimeMS > 0) {
197+
runMinTimeout(onRemaining, maxTimeMS);
198+
}
196199
return;
197200
}
198201
if (timeout == null) {
@@ -209,6 +212,22 @@ public void runMaxTimeMS(final LongConsumer onRemaining) {
209212

210213
}
211214

215+
private void runMinTimeout(final LongConsumer onRemaining, final long fixedMs) {
216+
Timeout timeout = timeoutIncludingRoundTrip();
217+
if (timeout != null) {
218+
timeout.run(MILLISECONDS, () -> {
219+
onRemaining.accept(fixedMs);
220+
},
221+
(renamingMs) -> {
222+
onRemaining.accept(Math.min(renamingMs, fixedMs));
223+
}, () -> {
224+
throwMongoTimeoutException("The operation exceeded the timeout limit.");
225+
});
226+
} else {
227+
onRemaining.accept(fixedMs);
228+
}
229+
}
230+
212231
private static void runWithFixedTimeout(final long ms, final LongConsumer onRemaining) {
213232
if (ms != 0) {
214233
onRemaining.accept(ms);
@@ -227,10 +246,14 @@ public void resetToDefaultMaxTime() {
227246
* <p>
228247
* NOTE: Suitable for static user-defined values only (i.e MaxAwaitTimeMS),
229248
* not for running timeouts that adjust dynamically (CSOT).
249+
*
250+
* If remaining CSOT timeout is less than this static timeout, then CSOT timeout will be used.
251+
*
230252
*/
231253
public void setMaxTimeOverride(final long maxTimeMS) {
232254
this.maxTimeSupplier = () -> maxTimeMS;
233255
}
256+
234257
/**
235258
* Disable the maxTimeMS override. This way the maxTimeMS will not
236259
* be appended to the command in the {@link CommandMessage}.

driver-core/src/test/resources/unified-test-format/client-side-operation-timeout/tailable-awaitData.json

Lines changed: 138 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"schemaVersion": "1.9",
55
"runOnRequirements": [
66
{
7-
"minServerVersion": "4.4"
7+
"minServerVersion": "4.4",
8+
"serverless": "forbid"
89
}
910
],
1011
"createEntities": [
@@ -419,6 +420,141 @@
419420
]
420421
}
421422
]
423+
},
424+
{
425+
"description": "apply remaining timeoutMS if less than maxAwaitTimeMS",
426+
"operations": [
427+
{
428+
"name": "failPoint",
429+
"object": "testRunner",
430+
"arguments": {
431+
"client": "failPointClient",
432+
"failPoint": {
433+
"configureFailPoint": "failCommand",
434+
"mode": {
435+
"times": 1
436+
},
437+
"data": {
438+
"failCommands": [
439+
"getMore"
440+
],
441+
"blockConnection": true,
442+
"blockTimeMS": 30
443+
}
444+
}
445+
}
446+
},
447+
{
448+
"name": "createFindCursor",
449+
"object": "collection",
450+
"arguments": {
451+
"filter": {
452+
"_id": 1
453+
},
454+
"cursorType": "tailableAwait",
455+
"batchSize": 1,
456+
"maxAwaitTimeMS": 100,
457+
"timeoutMS": 200
458+
},
459+
"saveResultAsEntity": "tailableCursor"
460+
},
461+
{
462+
"name": "iterateOnce",
463+
"object": "tailableCursor"
464+
},
465+
{
466+
"name": "iterateUntilDocumentOrError",
467+
"object": "tailableCursor",
468+
"expectError": {
469+
"isTimeoutError": true
470+
}
471+
}
472+
],
473+
"expectEvents": [
474+
{
475+
"client": "client",
476+
"ignoreExtraEvents": true,
477+
"events": [
478+
{
479+
"commandStartedEvent": {
480+
"commandName": "find",
481+
"databaseName": "test"
482+
}
483+
},
484+
{
485+
"commandStartedEvent": {
486+
"commandName": "getMore",
487+
"databaseName": "test",
488+
"command": {
489+
"maxTimeMS": {
490+
"$$lte": 100
491+
}
492+
}
493+
}
494+
},
495+
{
496+
"commandStartedEvent": {
497+
"commandName": "getMore",
498+
"databaseName": "test",
499+
"command": {
500+
"maxTimeMS": {
501+
"$$lte": 70
502+
}
503+
}
504+
}
505+
}
506+
]
507+
}
508+
]
509+
},
510+
{
511+
"description": "apply maxAwaitTimeMS if less than remaining timeout",
512+
"operations": [
513+
{
514+
"name": "createFindCursor",
515+
"object": "collection",
516+
"arguments": {
517+
"filter": {},
518+
"cursorType": "tailableAwait",
519+
"batchSize": 1,
520+
"maxAwaitTimeMS": 100,
521+
"timeoutMS": 200
522+
},
523+
"saveResultAsEntity": "tailableCursor"
524+
},
525+
{
526+
"name": "iterateOnce",
527+
"object": "tailableCursor"
528+
},
529+
{
530+
"name": "iterateOnce",
531+
"object": "tailableCursor"
532+
}
533+
],
534+
"expectEvents": [
535+
{
536+
"client": "client",
537+
"events": [
538+
{
539+
"commandStartedEvent": {
540+
"commandName": "find",
541+
"databaseName": "test"
542+
}
543+
},
544+
{
545+
"commandStartedEvent": {
546+
"commandName": "getMore",
547+
"databaseName": "test",
548+
"command": {
549+
"maxTimeMS": {
550+
"$$lte": 100
551+
}
552+
}
553+
}
554+
}
555+
]
556+
}
557+
]
422558
}
423559
]
424-
}
560+
}

driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestModifications.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ public static void applyCustomizations(final TestDef def) {
6565

6666
// client-side-operation-timeout (CSOT)
6767

68+
def.skipNoncompliantReactive("No good way to fulfill tryNext() requirement with a Publisher<T>")
69+
.directory("client-side-operation-timeout")
70+
.test("timeoutMS behaves correctly for tailable awaitData cursors", "apply remaining timeoutMS if less than maxAwaitTimeMS");
71+
6872
// TODO-JAVA-5712
6973

7074
// collection-management

0 commit comments

Comments
 (0)