Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSOT #1215

Draft
wants to merge 159 commits into
base: master
Choose a base branch
from
Draft

CSOT #1215

Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
159 commits
Select commit Hold shift + click to select a range
5ded734
Added ClientSideOperationTimeout class (#1171)
rozza Aug 22, 2023
83eeb10
CSOT: Added timeout to settings & connection string (#1173)
rozza Aug 22, 2023
087973e
Merge remote-tracking branch 'upstream/master' into CSOT
katcharov Sep 12, 2023
8f710f3
Replace Timeout implementation with interface, introduce StartTime in…
katcharov Sep 22, 2023
432bcb0
Added TimeoutSettings
rozza Sep 25, 2023
158b69c
Refactor to use Timeout for server selection (#1202)
katcharov Sep 27, 2023
4b92ec6
Checkstyle fix
rozza Sep 29, 2023
7334f5e
Renamed ClientSideOperationTimeout to TimeoutContext
rozza Sep 29, 2023
10beb22
Added getTimeoutSettings to Operation interfaces
rozza Sep 29, 2023
aee66e4
OperationContext promotion
rozza Sep 29, 2023
bcdc0eb
Cluster Binding now creates the OperationContext
rozza Sep 29, 2023
46f5eba
BindingContext now only contains OperationContext
rozza Sep 29, 2023
87b7843
Propogate Operation Context
rozza Sep 29, 2023
511a3c3
CommandProtocol is now immutable
rozza Sep 29, 2023
0ecc3f5
Add CommandCreator support to CommandReadOperation
rozza Sep 29, 2023
767bb1c
Update Tests regarding OperationContext
rozza Sep 29, 2023
1e769b0
Merge branch 'master' into CSOT-merge
rozza Sep 29, 2023
755adfd
Merge remote-tracking branch 'upstream/master' into CSOT
katcharov Oct 4, 2023
c4ccc24
Merge branch 'master' into CSOT
rozza Oct 9, 2023
bdc2abb
Merge branch 'master' into CSOT
rozza Oct 9, 2023
c442689
Merge branch 'master' into CSOT
rozza Oct 9, 2023
2a0707d
Merge branch 'master' into CSOT
rozza Oct 10, 2023
35d82be
Fix codenarc
rozza Oct 10, 2023
a9a3b2d
Spotbugs fixes / exclusions
rozza Oct 10, 2023
4b002c0
Refactor to obtain timeout from OperationContext for server selection…
katcharov Oct 12, 2023
d65d27f
Fix minor test failure, checkstyle
katcharov Oct 12, 2023
e8bdab5
Merge branch 'master' into CSOT
rozza Oct 17, 2023
a881808
Update BindingContext Javadoc
rozza Oct 19, 2023
ea6c37c
Obtain waitQueue and connection timeouts from OperationContext (#1228)
katcharov Oct 30, 2023
41bcec3
Apply timeout to server selection (#1226)
katcharov Oct 30, 2023
12c38a0
Merge branch 'master' into CSOT
rozza Nov 1, 2023
272a7c4
Ensure placeholder helpers allow tests to run
rozza Nov 1, 2023
8520e58
Fix server selection test performance
jyemin Nov 1, 2023
8f8fc66
Fix connection pool tests
jyemin Nov 1, 2023
6bceecc
Fix ClientSessionBindingSpecification test
jyemin Nov 1, 2023
1f62d92
Fix slow connection pool test
jyemin Nov 1, 2023
b7d9e34
fix broken server session pool test
jyemin Nov 1, 2023
ef3d2fe
Use correct timeout in connection pool tests
jyemin Nov 1, 2023
5c1da90
Merge branch 'master' into CSOT
rozza Nov 2, 2023
8553c8c
Updated ClientSideOperationsTimeoutProseTests
rozza Nov 3, 2023
39b311d
Merge branch 'master' into CSOT
rozza Nov 7, 2023
80796c0
Fix BaseCluster logging for infinite timeouts
rozza Nov 7, 2023
8eb7297
Merge branch 'master' into CSOT
rozza Nov 9, 2023
f5051af
Merge branch 'master' into CSOT
rozza Nov 9, 2023
3ad0b8a
Assert connection source immediately in killcursors
rozza Nov 9, 2023
cfb46b9
Correct merge commit issue in test
rozza Nov 9, 2023
8079234
Added minRoundTripTime to ServerDescription (#1267)
rozza Nov 30, 2023
88985a1
Added Cursor timeoutMode
rozza Nov 9, 2023
c7e703e
Added a FlakyTest annotation for junit 5 tests
rozza Nov 27, 2023
f6cc958
Annotated racy client side operation timeout prose tests as flaky
rozza Nov 27, 2023
0154b69
RecentSamples has to be thread safe
rozza Dec 6, 2023
7c5d986
Merge branch 'master' into CSOT-master
rozza Dec 6, 2023
b401dc7
Fix merge error in FindOperationUnitSpecification
rozza Dec 6, 2023
1f5b273
Merge branch 'master' into CSOT
rozza Dec 7, 2023
d137d7e
TimeContext#getMaxTimeMS accounts for minRoundTrip
rozza Nov 30, 2023
24a8827
Check timeout remaining before writing / reading
rozza Dec 4, 2023
5972d7e
Add OperationContext to Stream read / write methods
rozza Dec 7, 2023
7559f3d
Implement stream read and write timeout logic
rozza Dec 7, 2023
8d2b5c8
Fix `onErrorDropped` logged message (#1281)
rozza Jan 3, 2024
1a3e3a8
Deprecate options: maxTimeMS, maxCommitTimeMS for CRUD methods. (#1277)
vbabanin Jan 4, 2024
79fc95d
Merge branch 'master' into CSOT
rozza Jan 4, 2024
e8e91e3
Fix ListCollectionNamesPublisherImplTest and deprecate the ListCollec…
rozza Jan 4, 2024
b2d7092
Deprecated ListCollectionNamesIterable#maxTime
rozza Jan 4, 2024
1d386ec
Kotlin and Scala ListCollectionNames maxtime deprecations
rozza Jan 4, 2024
0d884a4
Update ListCollectionsOperationSpecification for CSOT
rozza Jan 5, 2024
f017080
Fix static analysis and deprecation warnings
rozza Jan 5, 2024
4df0945
CSOT Prose test updates
rozza Jan 5, 2024
b700def
CSOT Prose test changestream only watch inserts
rozza Jan 5, 2024
fe2bdd2
CSOT Fix socket timeout logic
rozza Jan 5, 2024
746d9b9
CSOT disable async changestream prose test
rozza Jan 5, 2024
452a292
FlakyTest ensure failures that eventually pass dont fail CI
rozza Jan 8, 2024
0ad6de5
Merge branch 'master' into CSOT
rozza Jan 8, 2024
6f30e81
CSOT Prose tests - use custom namespaces for changestream test to red…
rozza Jan 8, 2024
5efcc84
CSOT prose tests - also use custom namespaces for tailable cursors]
rozza Jan 8, 2024
48e3284
CSOT Prose tests disable for serverless and use majority write concer…
rozza Jan 9, 2024
836ecb2
CSOT async apply same racy test assertion catch
rozza Jan 9, 2024
55ebb63
CSOT netty readtimeouts are tested via operation context and CSOT now
rozza Jan 9, 2024
30b5e46
Merge branch 'master' into CSOT
rozza Jan 10, 2024
5d3850c
Add client operation timeout to retry functionality. (#1266)
vbabanin Jan 11, 2024
bcf857c
Merge branch 'master' into CSOT
rozza Jan 11, 2024
df45463
Updated TimeoutContext#createMongoTimeoutException
rozza Jan 11, 2024
a9c5fb3
Minor: Updated javadocs @since 4.x to @since CSOT
rozza Jan 11, 2024
7646ee6
Ensure MongoOperationTimeoutException is not a resumable error
rozza Jan 16, 2024
17b05ad
Add CSOT to synchronous GridFS operations. (#1288)
vbabanin Jan 17, 2024
a0dc246
Enable socketTimeoutMS tests
rozza Jan 18, 2024
8ea9a39
Add CSOT to reactive GridFS operations. (#1289)
vbabanin Jan 18, 2024
fd89877
Numerically sorted csot tests
rozza Jan 19, 2024
d8f0501
Added InternalOperationContextFactory
rozza Jan 11, 2024
1267f5d
Added operation context to authentication
rozza Jan 17, 2024
08f44c8
Revert "Added operation context to authentication"
rozza Jan 23, 2024
7504dbb
Fix Added InternalOperationContextFactory merge
rozza Jan 23, 2024
b072606
Update serverSelectionTimeout terminology
rozza Jan 23, 2024
fde9740
Update serverSelectionTimeout terminology 2/2
rozza Jan 23, 2024
1f25088
Increase blocking time for test / reduce race
rozza Jan 23, 2024
f0ff634
Added extra timeout check before sending command started
rozza Jan 23, 2024
1a9785d
Disable CSOT related SDAM tests
rozza Jan 23, 2024
1873bf7
Temp disable tests
rozza Jan 24, 2024
8671e84
Merge branch 'master' into CSOT
rozza Jan 25, 2024
898e885
Add maxTimeMS support to CRUD operations. (#1297)
vbabanin Jan 26, 2024
de20b3c
Update TimeoutContext equality checks
rozza Feb 2, 2024
20602e0
All MongoExecutionTimeoutException as a timeout error until JAVA-5248…
rozza Feb 2, 2024
5ca354f
Ensure initial socket setup takes into account timeoutMS
rozza Feb 5, 2024
bbc2d10
Ensure SocketStream recalculates the timeout on each read (#1299)
rozza Feb 7, 2024
34c0dc0
Updated SocketStreamHelperSpecification
rozza Feb 7, 2024
92a1247
Added operation context to authentication (#1298)
rozza Feb 7, 2024
0842e32
Remove extra annotation on prose test
rozza Feb 8, 2024
144ce16
Suppress unchecked warnings for mocks in CommandHelperTest
rozza Feb 9, 2024
32ac958
Add MongoSocketReadTimeout to acceptable timeouts until JAVA-5248 is …
rozza Feb 13, 2024
0bb062d
Updated CSOT prose tests for reactive GridFS
rozza Feb 13, 2024
df69d7e
Added more time to the serverselection CSOT prose test
rozza Feb 13, 2024
bc9d242
Imports CSOT prose test
rozza Feb 13, 2024
a4f4224
Increase timeout limits to reduce race conditions.
rozza Feb 13, 2024
e4443dc
Fix AWSAuthenticationSpecification execute calls
rozza Feb 13, 2024
657b972
Fix GSSAPIAuthenticationSpecification execute calls
rozza Feb 13, 2024
41a3902
Fix PlainAuthenticationSpecification execute calls
rozza Feb 13, 2024
4b019f3
Merge branch 'master' into CSOT
rozza Feb 20, 2024
88e93ea
Update AsyncRunnable for use with TimeoutContext
rozza Feb 20, 2024
2686904
Added Javadoc to MongoOperationTimeoutException constructors
rozza Feb 21, 2024
5966e95
Add CSOT to field Encryption/Decryption. (#1308)
vbabanin Feb 22, 2024
3ba95b0
Remove TimeoutSettings from Operations (#1309)
rozza Feb 27, 2024
d5acd00
Store computedServerSelectionTimeout so it can be reused. (#1312)
rozza Mar 4, 2024
45895b2
Updated the javadoc for runCommand. (#1323)
rozza Mar 7, 2024
ab1ec84
Add Client Operation Timeout to Change Streams (#1321)
vbabanin Mar 14, 2024
eed7590
Add unchecked suppression for reactive streams TimeoutHelperTest
rozza Mar 12, 2024
96fbf20
Adding Transaction and WithTransaction support
rozza Mar 15, 2024
5926666
Codestyle
rozza Mar 15, 2024
1cf0ed9
Added SuppressWarnings in some tests
rozza Mar 15, 2024
a16373e
Fix TimeoutContextTest case
rozza Mar 15, 2024
d1a9ed9
Disable tests for session timeoutMS individual operation overrides
rozza Mar 15, 2024
66a32da
Merge branch 'master' into CSOT-merge
rozza Mar 15, 2024
6d48613
Fix withTransactions tests
rozza Mar 18, 2024
4123367
Updated sessions timeoutMS tests to allow for extra events (abort tra…
rozza Mar 19, 2024
4e5ca75
Merge branch 'master' into CSOT
rozza Mar 19, 2024
9e957bb
Allow changing settings at the client level. (#1334)
rozza Mar 20, 2024
92f5776
Remove duplicate CSOT test assumptions
rozza Mar 20, 2024
3f41bf4
Deprecate timeout options. (#1346)
vbabanin Mar 22, 2024
6a0ae9d
Validate timeout and timeunit values (#1348)
rozza Mar 26, 2024
b89ce8e
Centralize appending of maxTimeMS (#1333)
vbabanin Mar 26, 2024
d0ba371
Merge branch 'master' into CSOT
rozza Mar 26, 2024
233f524
Merge branch 'master' into CSOT
rozza Apr 3, 2024
6d625e0
Improve debugging of dropped onError when tests fail
rozza Apr 3, 2024
24bf543
Fix newline in debugging onError dropped
rozza Apr 3, 2024
8a320c2
Merge branch 'master' into CSOT
rozza Apr 3, 2024
b169c3a
Merge branch 'master' into CSOT
rozza Apr 5, 2024
4e97f21
Ensure encryption timeouts are enough for testing against
rozza Apr 5, 2024
59739dd
Updated the unified specs tests (#1351)
rozza Apr 8, 2024
3b6ba32
Replace Timeout methods with branching "run" methods (#1349)
katcharov Apr 15, 2024
98c5bd4
CSOT error transformation (#1360)
vbabanin Apr 16, 2024
235adf4
Override collection/database with infinite timeout. (#1350)
vbabanin Apr 18, 2024
4a15e31
Ignore wTimeoutMS in WriteConcern when timeoutMS is set (#1368)
vbabanin Apr 22, 2024
ffc21e6
Undeprecate timeout APIs (#1369)
vbabanin Apr 22, 2024
997e92f
Merge branch 'master' into CSOT
vbabanin Apr 22, 2024
b02a5f9
Fix regression in timeout handling. (#1373)
vbabanin Apr 29, 2024
dca0278
Ensure TimeoutContext is present for a subsequent commit operation. (…
vbabanin May 2, 2024
2fdae3b
Mark CSOT feature as Alpha (#1372)
vbabanin May 3, 2024
1f30837
Fix race condition in retry logic. (#1377)
vbabanin May 7, 2024
0d2d8e8
Remove RTT check before reading a response from the server. (#1391)
vbabanin May 18, 2024
2b4dc77
CSOT: Master into csot merge (#1397)
vbabanin May 24, 2024
9f22195
Merge branch 'refs/heads/master' into CSOT
vbabanin May 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle
Expand Up @@ -157,6 +157,7 @@ configure(scalaProjects) {
"-unchecked",
"-language:reflectiveCalls",
"-Wconf:cat=deprecation:ws,any:e",
"-Wconf:msg=While parsing annotations in:silent",
"-Xlint:strict-unsealed-patmat"
]
}
Expand Down
24 changes: 24 additions & 0 deletions config/spotbugs/exclude.xml
Expand Up @@ -277,4 +277,28 @@
<Bug pattern="NP_NONNULL_PARAM_VIOLATION"/>
</Match>

<!-- Ignoring await return; intended to be used in a loop -->
<Match>
<Class name="com.mongodb.internal.time.Timeout"/>
<Method name="awaitOn"/>
<Bug pattern="RV_RETURN_VALUE_IGNORED_BAD_PRACTICE"/>
</Match>
<Match>
<Class name="com.mongodb.internal.time.Timeout"/>
<Method name="awaitOn"/>
<Bug pattern="RV_RETURN_VALUE_IGNORED"/>
</Match>
<Match>
<Class name="com.mongodb.internal.time.Timeout"/>
<Method name="awaitOn"/>
<Bug pattern="WA_AWAIT_NOT_IN_LOOP"/>
</Match>

<!-- Void method returning null but @NotNull API -->
<Match>
<Class name="com.mongodb.internal.operation.DropIndexOperation"/>
<Method name="execute"/>
<Bug pattern="NP_NONNULL_RETURN_VIOLATION"/>
</Match>

</FindBugsFilter>
84 changes: 73 additions & 11 deletions driver-core/src/main/com/mongodb/ConnectionString.java
Expand Up @@ -127,9 +127,11 @@
* <li>{@code sslInvalidHostNameAllowed=true|false}: Whether to allow invalid host names for TLS connections.</li>
* <li>{@code tlsAllowInvalidHostnames=true|false}: Whether to allow invalid host names for TLS connections. Supersedes the
* sslInvalidHostNameAllowed option</li>
* <li>{@code timeoutMS=ms}: Time limit for the full execution of an operation.</li>
* <li>{@code connectTimeoutMS=ms}: How long a connection can take to be opened before timing out.</li>
* <li>{@code socketTimeoutMS=ms}: How long a receive on a socket can take before timing out.
* This option is the same as {@link SocketSettings#getReadTimeout(TimeUnit)}.</li>
* This option is the same as {@link SocketSettings#getReadTimeout(TimeUnit)}.
* Deprecated, use {@code timeoutMS} instead.</li>
* <li>{@code maxIdleTimeMS=ms}: Maximum idle time of a pooled connection. A connection that exceeds this limit will be closed</li>
* <li>{@code maxLifeTimeMS=ms}: Maximum life time of a pooled connection. A connection that exceeds this limit will be closed</li>
* </ul>
Expand All @@ -149,7 +151,7 @@
* <li>{@code waitQueueTimeoutMS=ms}: The maximum duration to wait until either:
* an {@linkplain ConnectionCheckedOutEvent in-use connection} becomes {@linkplain ConnectionCheckedInEvent available},
* or a {@linkplain ConnectionCreatedEvent connection is created} and begins to be {@linkplain ConnectionReadyEvent established}.
* See {@link #getMaxWaitTime()} for more details.</li>
* See {@link #getMaxWaitTime()} for more details. . Deprecated, use {@code timeoutMS} instead.</li>
* <li>{@code maxConnecting=n}: The maximum number of connections a pool may be establishing concurrently.</li>
* </ul>
* <p>Write concern configuration:</p>
Expand Down Expand Up @@ -177,7 +179,7 @@
* <li>{@code wtimeoutMS=ms}
* <ul>
* <li>The driver adds { wtimeout : ms } to all write commands. Implies {@code safe=true}.</li>
* <li>Used in combination with {@code w}</li>
* <li>Used in combination with {@code w}. Deprecated, use {@code timeoutMS} instead</li>
* </ul>
* </li>
* </ul>
Expand Down Expand Up @@ -296,6 +298,7 @@ public class ConnectionString {
private Integer maxConnectionLifeTime;
private Integer maxConnecting;
private Integer connectTimeout;
private Long timeout;
private Integer socketTimeout;
private Boolean sslEnabled;
private Boolean sslInvalidHostnameAllowed;
Expand Down Expand Up @@ -485,6 +488,7 @@ public ConnectionString(final String connectionString, @Nullable final DnsClient

credential = createCredentials(combinedOptionsMaps, userName, password);
warnOnUnsupportedOptions(combinedOptionsMaps);
warnDeprecatedTimeouts(combinedOptionsMaps);
}

private static final Set<String> GENERAL_OPTIONS_KEYS = new LinkedHashSet<>();
Expand All @@ -493,16 +497,18 @@ public ConnectionString(final String connectionString, @Nullable final DnsClient
private static final Set<String> WRITE_CONCERN_KEYS = new HashSet<>();
private static final Set<String> COMPRESSOR_KEYS = new HashSet<>();
private static final Set<String> ALL_KEYS = new HashSet<>();
private static final Set<String> DEPRECATED_TIMEOUT_KEYS = new HashSet<>();

static {
GENERAL_OPTIONS_KEYS.add("minpoolsize");
GENERAL_OPTIONS_KEYS.add("maxpoolsize");
GENERAL_OPTIONS_KEYS.add("timeoutms");
GENERAL_OPTIONS_KEYS.add("sockettimeoutms");
GENERAL_OPTIONS_KEYS.add("waitqueuetimeoutms");
GENERAL_OPTIONS_KEYS.add("connecttimeoutms");
GENERAL_OPTIONS_KEYS.add("maxidletimems");
GENERAL_OPTIONS_KEYS.add("maxlifetimems");
GENERAL_OPTIONS_KEYS.add("maxconnecting");
GENERAL_OPTIONS_KEYS.add("sockettimeoutms");

// Order matters here: Having tls after ssl means than the tls option will supersede the ssl option when both are set
GENERAL_OPTIONS_KEYS.add("ssl");
Expand Down Expand Up @@ -564,6 +570,10 @@ public ConnectionString(final String connectionString, @Nullable final DnsClient
ALL_KEYS.addAll(READ_PREFERENCE_KEYS);
ALL_KEYS.addAll(WRITE_CONCERN_KEYS);
ALL_KEYS.addAll(COMPRESSOR_KEYS);

DEPRECATED_TIMEOUT_KEYS.add("sockettimeoutms");
DEPRECATED_TIMEOUT_KEYS.add("waitqueuetimeoutms");
DEPRECATED_TIMEOUT_KEYS.add("wtimeoutms");
}

// Any options contained in the connection string completely replace the corresponding options specified in TXT records,
Expand All @@ -577,15 +587,23 @@ private Map<String, List<String>> combineOptionsMaps(final Map<String, List<Stri


private void warnOnUnsupportedOptions(final Map<String, List<String>> optionsMap) {
for (final String key : optionsMap.keySet()) {
if (!ALL_KEYS.contains(key)) {
if (LOGGER.isWarnEnabled()) {
LOGGER.warn(format("Connection string contains unsupported option '%s'.", key));
}
}
if (LOGGER.isWarnEnabled()) {
optionsMap.keySet()
.stream()
.filter(k -> !ALL_KEYS.contains(k))
.forEach(k -> LOGGER.warn(format("Connection string contains unsupported option '%s'.", k)));
}
}
private void warnDeprecatedTimeouts(final Map<String, List<String>> optionsMap) {
if (LOGGER.isWarnEnabled()) {
optionsMap.keySet()
.stream()
.filter(DEPRECATED_TIMEOUT_KEYS::contains)
.forEach(k -> LOGGER.warn(format("Use of deprecated timeout option: '%s'. Prefer 'timeoutMS' instead.", k)));
}
}


private void translateOptions(final Map<String, List<String>> optionsMap) {
boolean tlsInsecureSet = false;
boolean tlsAllowInvalidHostnamesSet = false;
Expand Down Expand Up @@ -620,6 +638,9 @@ private void translateOptions(final Map<String, List<String>> optionsMap) {
case "sockettimeoutms":
socketTimeout = parseInteger(value, "sockettimeoutms");
break;
case "timeoutms":
timeout = parseLong(value, "timeoutms");
break;
case "proxyhost":
proxyHost = value;
break;
Expand Down Expand Up @@ -1140,6 +1161,15 @@ private int parseInteger(final String input, final String key) {
}
}

private long parseLong(final String input, final String key) {
try {
return Long.parseLong(input);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(format("The connection string contains an invalid value for '%s'. "
+ "'%s' is not a valid long", key, input));
}
}

private List<String> parseHosts(final List<String> rawHosts) {
if (rawHosts.size() == 0){
throw new IllegalArgumentException("The connection string must contain at least one host");
Expand Down Expand Up @@ -1514,6 +1544,37 @@ public Integer getMaxConnecting() {
return maxConnecting;
}

/**
* The time limit for the full execution of an operation in milliseconds.
*
* <p>If set the following deprecated options will be ignored:
* {@code waitQueueTimeoutMS}, {@code socketTimeoutMS}, {@code wTimeoutMS}, {@code maxTimeMS} and {@code maxCommitTimeMS}</p>
*
* <ul>
* <li>{@code null} means that the timeout mechanism for operations will defer to using:
* <ul>
* <li>{@code waitQueueTimeoutMS}: The maximum wait time in milliseconds that a thread may wait for a connection to become
* available</li>
* <li>{@code socketTimeoutMS}: How long a send or receive on a socket can take before timing out.</li>
* <li>{@code wTimeoutMS}: How long the server will wait for the write concern to be fulfilled before timing out.</li>
* <li>{@code maxTimeMS}: The cumulative time limit for processing operations on a cursor.
* See: <a href="https://docs.mongodb.com/manual/reference/method/cursor.maxTimeMS">cursor.maxTimeMS</a>.</li>
* <li>{@code maxCommitTimeMS}: The maximum amount of time to allow a single {@code commitTransaction} command to execute.
* See: {@link TransactionOptions#getMaxCommitTime}.</li>
* </ul>
* </li>
* <li>{@code 0} means infinite timeout.</li>
* <li>{@code > 0} The time limit to use for the full execution of an operation.</li>
* </ul>
*
* @return the time limit for the full execution of an operation in milliseconds or null.
* @since 4.x
*/
@Nullable
public Long getTimeout() {
return timeout;
}

/**
* Gets the socket connect timeout specified in the connection string.
* @return the socket connect timeout
Expand Down Expand Up @@ -1704,6 +1765,7 @@ public boolean equals(final Object o) {
&& Objects.equals(maxConnectionLifeTime, that.maxConnectionLifeTime)
&& Objects.equals(maxConnecting, that.maxConnecting)
&& Objects.equals(connectTimeout, that.connectTimeout)
&& Objects.equals(timeout, that.timeout)
&& Objects.equals(socketTimeout, that.socketTimeout)
&& Objects.equals(proxyHost, that.proxyHost)
&& Objects.equals(proxyPort, that.proxyPort)
Expand All @@ -1726,7 +1788,7 @@ public boolean equals(final Object o) {
public int hashCode() {
return Objects.hash(credential, isSrvProtocol, hosts, database, collection, directConnection, readPreference,
writeConcern, retryWrites, retryReads, readConcern, minConnectionPoolSize, maxConnectionPoolSize, maxWaitTime,
maxConnectionIdleTime, maxConnectionLifeTime, maxConnecting, connectTimeout, socketTimeout, sslEnabled,
maxConnectionIdleTime, maxConnectionLifeTime, maxConnecting, connectTimeout, timeout, socketTimeout, sslEnabled,
sslInvalidHostnameAllowed, requiredReplicaSetName, serverSelectionTimeout, localThreshold, heartbeatFrequency,
applicationName, compressorList, uuidRepresentation, srvServiceName, srvMaxHosts, proxyHost, proxyPort,
proxyUsername, proxyPassword);
Expand Down
84 changes: 82 additions & 2 deletions driver-core/src/main/com/mongodb/MongoClientSettings.java
Expand Up @@ -50,7 +50,9 @@
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static com.mongodb.assertions.Assertions.isTrue;
import static com.mongodb.assertions.Assertions.isTrueArgument;
import static com.mongodb.assertions.Assertions.notNull;
import static java.util.Arrays.asList;
Expand Down Expand Up @@ -114,6 +116,8 @@ public final class MongoClientSettings {
private final ContextProvider contextProvider;
private final DnsClient dnsClient;
private final InetAddressResolver inetAddressResolver;
@Nullable
private final Long timeoutMS;

/**
* Gets the default codec registry. It includes the following providers:
Expand Down Expand Up @@ -232,6 +236,7 @@ public static final class Builder {

private int heartbeatConnectTimeoutMS;
private int heartbeatSocketTimeoutMS;
private Long timeoutMS;

private ContextProvider contextProvider;
private DnsClient dnsClient;
Expand All @@ -255,6 +260,7 @@ private Builder(final MongoClientSettings settings) {
uuidRepresentation = settings.getUuidRepresentation();
serverApi = settings.getServerApi();
dnsClient = settings.getDnsClient();
timeoutMS = settings.getTimeout(MILLISECONDS);
inetAddressResolver = settings.getInetAddressResolver();
transportSettings = settings.getTransportSettings();
streamFactoryFactory = settings.getStreamFactoryFactory();
Expand Down Expand Up @@ -318,6 +324,9 @@ public Builder applyConnectionString(final ConnectionString connectionString) {
if (connectionString.getWriteConcern() != null) {
writeConcern = connectionString.getWriteConcern();
}
if (connectionString.getTimeout() != null) {
timeoutMS = connectionString.getTimeout();
}
return this;
}

Expand Down Expand Up @@ -690,6 +699,40 @@ public Builder inetAddressResolver(@Nullable final InetAddressResolver inetAddre
return this;
}


/**
* Sets the time limit for the full execution of an operation.
*
* <ul>
* <li>{@code null} means that the timeout mechanism for operations will defer to using:
* <ul>
* <li>{@code waitQueueTimeoutMS}: The maximum wait time in milliseconds that a thread may wait for a connection to become
* available</li>
* <li>{@code socketTimeoutMS}: How long a send or receive on a socket can take before timing out.</li>
* <li>{@code wTimeoutMS}: How long the server will wait for the write concern to be fulfilled before timing out.</li>
* <li>{@code maxTimeMS}: The cumulative time limit for processing operations on a cursor.
* See: <a href="https://docs.mongodb.com/manual/reference/method/cursor.maxTimeMS">cursor.maxTimeMS</a>.</li>
* <li>{@code maxCommitTimeMS}: The maximum amount of time to allow a single {@code commitTransaction} command to execute.
* See: {@link TransactionOptions#getMaxCommitTime}.</li>
* </ul>
* </li>
* <li>{@code 0} means infinite timeout.</li>
* <li>{@code > 0} The time limit to use for the full execution of an operation.</li>
* </ul>
*
* @param timeout the timeout
* @param timeUnit the time unit
* @return this
* @since 4.x
* @see #getTimeout
*/
public Builder timeout(final long timeout, final TimeUnit timeUnit) {
isTrueArgument("timeoutMS must be >= 0", timeout >= 0);
this.timeoutMS = MILLISECONDS.convert(timeout, timeUnit);
return this;
}


// Package-private to provide interop with MongoClientOptions
Builder heartbeatConnectTimeoutMS(final int heartbeatConnectTimeoutMS) {
this.heartbeatConnectTimeoutMS = heartbeatConnectTimeoutMS;
Expand Down Expand Up @@ -883,6 +926,38 @@ public ServerApi getServerApi() {
return serverApi;
}

/**
* The time limit for the full execution of an operation.
*
* <p>If set the following deprecated options will be ignored:
* {@code waitQueueTimeoutMS}, {@code socketTimeoutMS}, {@code wTimeoutMS}, {@code maxTimeMS} and {@code maxCommitTimeMS}</p>
*
* <ul>
* <li>{@code null} means that the timeout mechanism for operations will defer to using:
* <ul>
* <li>{@code waitQueueTimeoutMS}: The maximum wait time in milliseconds that a thread may wait for a connection to become
* available</li>
* <li>{@code socketTimeoutMS}: How long a send or receive on a socket can take before timing out.</li>
* <li>{@code wTimeoutMS}: How long the server will wait for the write concern to be fulfilled before timing out.</li>
* <li>{@code maxTimeMS}: The cumulative time limit for processing operations on a cursor.
* See: <a href="https://docs.mongodb.com/manual/reference/method/cursor.maxTimeMS">cursor.maxTimeMS</a>.</li>
* <li>{@code maxCommitTimeMS}: The maximum amount of time to allow a single {@code commitTransaction} command to execute.
* See: {@link TransactionOptions#getMaxCommitTime}.</li>
* </ul>
* </li>
* <li>{@code 0} means infinite timeout.</li>
* <li>{@code > 0} The time limit to use for the full execution of an operation.</li>
* </ul>
*
* @param timeUnit the time unit
* @return the timeout in the given time unit
* @since 4.x
*/
@Nullable
public Long getTimeout(final TimeUnit timeUnit) {
return timeoutMS == null ? null : timeUnit.convert(timeoutMS, MILLISECONDS);
}

/**
* Gets the auto-encryption settings.
* <p>
Expand Down Expand Up @@ -1034,7 +1109,8 @@ public boolean equals(final Object o) {
&& Objects.equals(autoEncryptionSettings, that.autoEncryptionSettings)
&& Objects.equals(dnsClient, that.dnsClient)
&& Objects.equals(inetAddressResolver, that.inetAddressResolver)
&& Objects.equals(contextProvider, that.contextProvider);
&& Objects.equals(contextProvider, that.contextProvider)
&& Objects.equals(timeoutMS, that.timeoutMS);
}

@Override
Expand All @@ -1043,7 +1119,8 @@ public int hashCode() {
streamFactoryFactory, commandListeners, codecRegistry, loggerSettings, clusterSettings, socketSettings,
heartbeatSocketSettings, connectionPoolSettings, serverSettings, sslSettings, applicationName, compressorList,
uuidRepresentation, serverApi, autoEncryptionSettings, heartbeatSocketTimeoutSetExplicitly,
heartbeatConnectTimeoutSetExplicitly, dnsClient, inetAddressResolver, contextProvider);
heartbeatConnectTimeoutSetExplicitly, dnsClient, inetAddressResolver, contextProvider, timeoutMS);

}

@Override
Expand Down Expand Up @@ -1074,10 +1151,12 @@ public String toString() {
+ ", dnsClient=" + dnsClient
+ ", inetAddressResolver=" + inetAddressResolver
+ ", contextProvider=" + contextProvider
+ ", timeoutMS=" + timeoutMS
+ '}';
}

private MongoClientSettings(final Builder builder) {
isTrue("timeoutMS > 0 ", builder.timeoutMS == null || builder.timeoutMS >= 0);
readPreference = builder.readPreference;
writeConcern = builder.writeConcern;
retryWrites = builder.retryWrites;
Expand Down Expand Up @@ -1113,5 +1192,6 @@ private MongoClientSettings(final Builder builder) {
heartbeatSocketTimeoutSetExplicitly = builder.heartbeatSocketTimeoutMS != 0;
heartbeatConnectTimeoutSetExplicitly = builder.heartbeatConnectTimeoutMS != 0;
contextProvider = builder.contextProvider;
timeoutMS = builder.timeoutMS;
}
}