Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
e6083b4
Add support for server selection's deprioritized servers to all topol…
vbabanin Jan 12, 2026
de2856b
Remove global OperationContext in tests as it has mutable state.
vbabanin Jan 15, 2026
689d6cb
Add more test-cases.
vbabanin Jan 17, 2026
a8ddab2
Fix static checks.
vbabanin Jan 17, 2026
1eddabf
Allow invoking connect.
vbabanin Jan 18, 2026
d62a576
Update driver-core/src/main/com/mongodb/internal/connection/Operation…
vbabanin Mar 4, 2026
777ced9
Update driver-core/src/test/unit/com/mongodb/connection/ServerSelecti…
vbabanin Mar 5, 2026
85cc1aa
Update driver-core/src/test/unit/com/mongodb/connection/ServerSelecti…
vbabanin Mar 5, 2026
893d419
Use "create" prefix consistently.
vbabanin Mar 3, 2026
19ab190
Remove craeteNewOperationContext.
vbabanin Mar 4, 2026
05beaf2
Change visibility modifier.
vbabanin Mar 4, 2026
0bf110b
Rename applyDeprioritization method to apply.
vbabanin Mar 4, 2026
46b9b8d
Add TODO comments for performance optimization.
vbabanin Mar 4, 2026
cd5dcf1
Add empty line.
vbabanin Mar 4, 2026
dfae55b
Return ALL_SERVERS from selector.
vbabanin Mar 4, 2026
bb54d82
Make heartbeatFrequencyMS a local variable.
vbabanin Mar 4, 2026
3bd9710
Revert to assumeFalse.
vbabanin Mar 4, 2026
1f38bc7
Use Junit4.
vbabanin Mar 5, 2026
70e1eeb
Convert comment to a class documentation comment.
vbabanin Mar 5, 2026
59b1aa1
Remove deprioritizedServerAddresses field.
vbabanin Mar 5, 2026
41849e7
Move inLatencyWindowServers to pre-try.
vbabanin Mar 5, 2026
cb3e7d6
Remove unnecessary symbol.
vbabanin Mar 5, 2026
793507a
Add assertion context.
vbabanin Mar 5, 2026
f4ab841
Remove redundant comment.
vbabanin Mar 5, 2026
11cf14a
Use immediate timeout.
vbabanin Mar 5, 2026
9017de8
Use MongoException instead of MongoConfigurationException.
vbabanin Mar 5, 2026
bc0f8da
Remove createTestCluster method.
vbabanin Mar 5, 2026
23332b2
Use com.mongodb.assertions.Assertions.fail for a Fake cluster.
vbabanin Mar 5, 2026
b4fe6f3
Change message.
vbabanin Mar 5, 2026
7a4dcfd
Update driver-core/src/test/unit/com/mongodb/internal/connection/Serv…
vbabanin Mar 5, 2026
2e38a65
Use MongoMockito.
vbabanin Mar 5, 2026
d1868a3
Remove TODO.
vbabanin Mar 5, 2026
021e7f5
Use withNewServerDeprioritization.
vbabanin Mar 5, 2026
44a66c1
Make ServerDeprioritization private.
vbabanin Mar 5, 2026
9f047b7
Remove unused methods.
vbabanin Mar 5, 2026
a1c052a
Reuse OperationContext.
vbabanin Mar 5, 2026
704d829
Use a documentation comment.
vbabanin Mar 5, 2026
3736c17
Use VisibleForTesting(otherwise = PROTECTED).
vbabanin Mar 5, 2026
817a5c5
Reuse OperatioContext.
vbabanin Mar 5, 2026
3373c14
Change comments.
vbabanin Mar 5, 2026
0cb9bf2
Change comments.
vbabanin Mar 5, 2026
ae8d201
Use createOperationContext.
vbabanin Mar 5, 2026
446f8ff
Address review feedback
vbabanin Apr 16, 2026
2bf6aaa
Limit server selection deprioritization to system overloaded errors o…
vbabanin Apr 16, 2026
1f4c0c9
Update driver-core/src/test/unit/com/mongodb/connection/ServerSelecti…
vbabanin Apr 16, 2026
29199e5
Update driver-core/src/main/com/mongodb/internal/connection/Operation…
vbabanin Apr 16, 2026
4d03cd2
Update driver-core/src/main/com/mongodb/internal/connection/Operation…
vbabanin Apr 16, 2026
4e69816
Update driver-core/src/main/com/mongodb/internal/connection/Operation…
vbabanin Apr 16, 2026
40aecc7
Update driver-core/src/test/unit/com/mongodb/internal/connection/Defa…
vbabanin Apr 16, 2026
a911780
Address PR review feedback
vbabanin Apr 16, 2026
8f1fbbb
Update visibility.
vbabanin Apr 16, 2026
0b8a594
Remove unused imports.
vbabanin Apr 16, 2026
6814a58
Change to find.
vbabanin Apr 17, 2026
08c1164
Fix config.
vbabanin Apr 17, 2026
aded7d7
Add enableOverloadRetargeting API
vbabanin Apr 17, 2026
0ba949c
Add TODO.
vbabanin Apr 17, 2026
a69ed65
Add unit tests.
vbabanin Apr 17, 2026
bef1d23
Add tests and javadoc.
vbabanin Apr 18, 2026
ac73678
Fix test issue.
vbabanin Apr 18, 2026
5ea540a
Fix test issue.
vbabanin Apr 18, 2026
0273bde
Fix comma.
vbabanin Apr 18, 2026
d113f9f
Add equals and hashcode test.
vbabanin Apr 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions driver-core/src/main/com/mongodb/ConnectionString.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.mongodb.annotations.Alpha;
import com.mongodb.annotations.Reason;
import com.mongodb.connection.ClusterSettings;
import com.mongodb.connection.ClusterType;
import com.mongodb.connection.ConnectionPoolSettings;
import com.mongodb.connection.ServerMonitoringMode;
import com.mongodb.connection.ServerSettings;
Expand Down Expand Up @@ -272,6 +273,9 @@
* Defaults to true.</li>
* <li>{@code retryReads=true|false}. If true the driver will retry supported read operations if they fail due to a network error.
* Defaults to true.</li>
* <li>{@code enableOverloadRetargeting=true|false}. If true the driver may route a request to a different server on a subsequent
* retry attempt if the previously used server is overloaded. Does not take effect for {@linkplain ClusterType#SHARDED sharded clusters}.
* Defaults to false.</li>
* <li>{@code uuidRepresentation=unspecified|standard|javaLegacy|csharpLegacy|pythonLegacy}. See
* {@link MongoClientSettings#getUuidRepresentation()} for documentation of semantics of this parameter. Defaults to "javaLegacy", but
* will change to "unspecified" in the next major release.</li>
Expand Down Expand Up @@ -308,6 +312,7 @@ public class ConnectionString {
private WriteConcern writeConcern;
private Boolean retryWrites;
private Boolean retryReads;
private Boolean enableOverloadRetargeting;
private ReadConcern readConcern;

private Integer minConnectionPoolSize;
Expand Down Expand Up @@ -558,6 +563,7 @@ public ConnectionString(final String connectionString, @Nullable final DnsClient
GENERAL_OPTIONS_KEYS.add("servermonitoringmode");
GENERAL_OPTIONS_KEYS.add("retrywrites");
GENERAL_OPTIONS_KEYS.add("retryreads");
GENERAL_OPTIONS_KEYS.add("enableoverloadretargeting");

GENERAL_OPTIONS_KEYS.add("appname");

Expand Down Expand Up @@ -706,6 +712,9 @@ private void translateOptions(final Map<String, List<String>> optionsMap) {
case "retryreads":
retryReads = parseBoolean(value, "retryreads");
break;
case "enableoverloadretargeting":
enableOverloadRetargeting = parseBoolean(value, "enableoverloadretargeting");
break;
case "uuidrepresentation":
uuidRepresentation = createUuidRepresentation(value);
break;
Expand Down Expand Up @@ -1473,7 +1482,7 @@ public Boolean getRetryWritesValue() {
/**
* <p>Gets whether reads should be retried if they fail due to a network error</p>
*
* @return the retryWrites value
* @return the retryReads value
* @since 3.11
* @mongodb.server.release 3.6
*/
Expand All @@ -1482,6 +1491,29 @@ public Boolean getRetryReads() {
return retryReads;
}

/**
* Gets whether overload retargeting is enabled.
*
* <p>When enabled, the previously selected servers on which attempts failed with an error
* {@linkplain MongoException#hasErrorLabel(String) having}
* the {@value MongoException#SYSTEM_OVERLOADED_ERROR_LABEL} label may be deprioritized during
* server selection on subsequent retry attempts. This applies to reads when retryReads is enabled,
* and to writes when retryWrites is enabled.</p>
*
* <p>This setting does not take effect for
* {@linkplain com.mongodb.connection.ClusterType#SHARDED sharded clusters}.</p>
*
* <p>Defaults to {@code false}.</p>
*
* @return the enableOverloadRetargeting value, or null if not set
* @see MongoClientSettings.Builder#enableOverloadRetargeting(boolean)
* @since 5.7
*/
@Nullable
public Boolean getEnableOverloadRetargeting() {
return enableOverloadRetargeting;
}

/**
* Gets the minimum connection pool size specified in the connection string.
* @return the minimum connection pool size
Expand Down Expand Up @@ -1795,6 +1827,7 @@ public boolean equals(final Object o) {
&& Objects.equals(writeConcern, that.writeConcern)
&& Objects.equals(retryWrites, that.retryWrites)
&& Objects.equals(retryReads, that.retryReads)
&& Objects.equals(enableOverloadRetargeting, that.enableOverloadRetargeting)
&& Objects.equals(readConcern, that.readConcern)
&& Objects.equals(minConnectionPoolSize, that.minConnectionPoolSize)
&& Objects.equals(maxConnectionPoolSize, that.maxConnectionPoolSize)
Expand Down Expand Up @@ -1826,8 +1859,8 @@ public boolean equals(final Object o) {
@Override
public int hashCode() {
return Objects.hash(credential, isSrvProtocol, hosts, database, collection, directConnection, readPreference,
writeConcern, retryWrites, retryReads, readConcern, minConnectionPoolSize, maxConnectionPoolSize, maxWaitTime,
maxConnectionIdleTime, maxConnectionLifeTime, maxConnecting, connectTimeout, timeout, socketTimeout, sslEnabled,
writeConcern, retryWrites, retryReads, enableOverloadRetargeting, readConcern, minConnectionPoolSize, maxConnectionPoolSize,
maxWaitTime, maxConnectionIdleTime, maxConnectionLifeTime, maxConnecting, connectTimeout, timeout, socketTimeout, sslEnabled,
sslInvalidHostnameAllowed, requiredReplicaSetName, serverSelectionTimeout, localThreshold, heartbeatFrequency,
serverMonitoringMode, applicationName, compressorList, uuidRepresentation, srvServiceName, srvMaxHosts, proxyHost,
proxyPort, proxyUsername, proxyPassword);
Expand Down
51 changes: 49 additions & 2 deletions driver-core/src/main/com/mongodb/MongoClientSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.mongodb.client.model.geojson.codecs.GeoJsonCodecProvider;
import com.mongodb.client.model.mql.ExpressionCodecProvider;
import com.mongodb.connection.ClusterSettings;
import com.mongodb.connection.ClusterType;
import com.mongodb.connection.ConnectionPoolSettings;
import com.mongodb.connection.ServerSettings;
import com.mongodb.connection.SocketSettings;
Expand Down Expand Up @@ -93,6 +94,7 @@ public final class MongoClientSettings {
private final WriteConcern writeConcern;
private final boolean retryWrites;
private final boolean retryReads;
private final boolean enableOverloadRetargeting;
private final ReadConcern readConcern;
private final MongoCredential credential;
private final TransportSettings transportSettings;
Expand Down Expand Up @@ -214,6 +216,7 @@ public static final class Builder {
private WriteConcern writeConcern = WriteConcern.ACKNOWLEDGED;
private boolean retryWrites = true;
private boolean retryReads = true;
private boolean enableOverloadRetargeting = false;
private ReadConcern readConcern = ReadConcern.DEFAULT;
private CodecRegistry codecRegistry = MongoClientSettings.getDefaultCodecRegistry();
private TransportSettings transportSettings;
Expand Down Expand Up @@ -255,6 +258,7 @@ private Builder(final MongoClientSettings settings) {
writeConcern = settings.getWriteConcern();
retryWrites = settings.getRetryWrites();
retryReads = settings.getRetryReads();
enableOverloadRetargeting = settings.getEnableOverloadRetargeting();
readConcern = settings.getReadConcern();
credential = settings.getCredential();
uuidRepresentation = settings.getUuidRepresentation();
Expand Down Expand Up @@ -314,6 +318,10 @@ public Builder applyConnectionString(final ConnectionString connectionString) {
if (retryReadsValue != null) {
retryReads = retryReadsValue;
}
Boolean enableOverloadRetargetingValue = connectionString.getEnableOverloadRetargeting();
if (enableOverloadRetargetingValue != null) {
enableOverloadRetargeting = enableOverloadRetargetingValue;
}
if (connectionString.getUuidRepresentation() != null) {
uuidRepresentation = connectionString.getUuidRepresentation();
}
Expand Down Expand Up @@ -456,6 +464,30 @@ public Builder retryReads(final boolean retryReads) {
return this;
}

/**
* Sets whether to enable overload retargeting.
*
* <p>When enabled, the previously selected servers on which attempts failed with an error
* {@linkplain MongoException#hasErrorLabel(String) having}
* the {@value MongoException#SYSTEM_OVERLOADED_ERROR_LABEL} label may be deprioritized during
* server selection on subsequent retry attempts. This applies to reads when
* {@linkplain #retryReads(boolean) retryReads} is enabled, and to writes when
* {@linkplain #retryWrites(boolean) retryWrites} is enabled.</p>
*
* <p>This setting does not take effect for {@linkplain ClusterType#SHARDED sharded clusters}.</p>
*
* <p>Defaults to {@code false}.</p>
*
* @param enableOverloadRetargeting whether to enable overload retargeting.
* @return this
* @see #getEnableOverloadRetargeting()
* @since 5.7
*/
public Builder enableOverloadRetargeting(final boolean enableOverloadRetargeting) {
this.enableOverloadRetargeting = enableOverloadRetargeting;
return this;
}

/**
* Sets the read concern.
*
Expand Down Expand Up @@ -807,6 +839,18 @@ public boolean getRetryReads() {
return retryReads;
}

/**
* Returns whether overload retargeting is enabled.
* See {@link Builder#enableOverloadRetargeting(boolean)} for more information.
*
* @return the enableOverloadRetargeting value
* @see Builder#enableOverloadRetargeting(boolean)
* @since 5.7
*/
public boolean getEnableOverloadRetargeting() {
return enableOverloadRetargeting;
}

/**
* The read concern to use.
*
Expand Down Expand Up @@ -1080,6 +1124,7 @@ public boolean equals(final Object o) {
MongoClientSettings that = (MongoClientSettings) o;
return retryWrites == that.retryWrites
&& retryReads == that.retryReads
&& enableOverloadRetargeting == that.enableOverloadRetargeting
&& heartbeatSocketTimeoutSetExplicitly == that.heartbeatSocketTimeoutSetExplicitly
&& heartbeatConnectTimeoutSetExplicitly == that.heartbeatConnectTimeoutSetExplicitly
&& Objects.equals(readPreference, that.readPreference)
Expand Down Expand Up @@ -1109,8 +1154,8 @@ public boolean equals(final Object o) {

@Override
public int hashCode() {
return Objects.hash(readPreference, writeConcern, retryWrites, retryReads, readConcern, credential, transportSettings,
commandListeners, codecRegistry, loggerSettings, clusterSettings, socketSettings,
return Objects.hash(readPreference, writeConcern, retryWrites, retryReads, enableOverloadRetargeting, readConcern, credential,
transportSettings, commandListeners, codecRegistry, loggerSettings, clusterSettings, socketSettings,
heartbeatSocketSettings, connectionPoolSettings, serverSettings, sslSettings, applicationName, compressorList,
uuidRepresentation, serverApi, autoEncryptionSettings, heartbeatSocketTimeoutSetExplicitly,
heartbeatConnectTimeoutSetExplicitly, dnsClient, inetAddressResolver, contextProvider, timeoutMS);
Expand All @@ -1124,6 +1169,7 @@ public String toString() {
+ ", writeConcern=" + writeConcern
+ ", retryWrites=" + retryWrites
+ ", retryReads=" + retryReads
+ ", enableOverloadRetargeting=" + enableOverloadRetargeting
+ ", readConcern=" + readConcern
+ ", credential=" + credential
+ ", transportSettings=" + transportSettings
Expand Down Expand Up @@ -1154,6 +1200,7 @@ private MongoClientSettings(final Builder builder) {
writeConcern = builder.writeConcern;
retryWrites = builder.retryWrites;
retryReads = builder.retryReads;
enableOverloadRetargeting = builder.enableOverloadRetargeting;
readConcern = builder.readConcern;
credential = builder.credential;
transportSettings = builder.transportSettings;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ abstract class BaseCluster implements Cluster {
private volatile ClusterDescription description;

BaseCluster(final ClusterId clusterId,
final ClusterSettings settings,
final ClusterableServerFactory serverFactory,
final ClientMetadata clientMetadata) {
final ClusterSettings settings,
final ClusterableServerFactory serverFactory,
final ClientMetadata clientMetadata) {
this.clusterId = notNull("clusterId", clusterId);
this.settings = notNull("settings", settings);
this.serverFactory = notNull("serverFactory", serverFactory);
Expand Down Expand Up @@ -159,7 +159,7 @@ public ServerTuple selectServer(final ServerSelector serverSelector, final Opera
if (serverTuple != null) {
ServerAddress serverAddress = serverTuple.getServerDescription().getAddress();
logServerSelectionSucceeded(operationContext, clusterId, serverAddress, serverSelector, currentDescription);
serverDeprioritization.updateCandidate(serverAddress);
serverDeprioritization.updateCandidate(serverAddress, currentDescription.getType());
return serverTuple;
}
computedServerSelectionTimeout.onExpired(() ->
Expand Down Expand Up @@ -302,7 +302,7 @@ private boolean handleServerSelectionRequest(
if (serverTuple != null) {
ServerAddress serverAddress = serverTuple.getServerDescription().getAddress();
logServerSelectionSucceeded(operationContext, clusterId, serverAddress, request.originalSelector, description);
serverDeprioritization.updateCandidate(serverAddress);
serverDeprioritization.updateCandidate(serverAddress, description.getType());
request.onResult(serverTuple, null);
return true;
}
Expand Down Expand Up @@ -361,8 +361,7 @@ private static ServerSelector getCompleteServerSelector(
final ClusterSettings settings) {
List<ServerSelector> selectors = Stream.of(
getRaceConditionPreFilteringSelector(serversSnapshot),
serverSelector,
serverDeprioritization.getServerSelector(),
serverDeprioritization.apply(serverSelector),
settings.getServerSelector(), // may be null
new LatencyMinimizingServerSelector(settings.getLocalThreshold(MILLISECONDS), MILLISECONDS),
AtMostTwoRandomServerSelector.instance(),
Expand Down
Loading