Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
385aa65
JAVA-6035: Add backpressure flag to connection handshake (#1906)
nhachicha Mar 5, 2026
f6046f2
Add `MongoException.SYSTEM_OVERLOADED_ERROR_LABEL`/`RETRYABLE_ERROR_L…
stIncMale Mar 24, 2026
6e09be7
JAVA-6055 Implement prose backpressure retryable writes tests (#1929)
stIncMale May 8, 2026
6f70ce3
Add `maxAdaptiveRetries` API (#1944)
stIncMale Apr 20, 2026
7893a8b
Add support for server selection's deprioritized servers (#1860)
vbabanin Apr 21, 2026
f9022e8
Implement prose backpressure tests (#1946)
stIncMale Apr 22, 2026
5cda934
Add `enableOverloadRetargeting` API (#1943)
vbabanin Apr 23, 2026
2458cf9
Add handshake prose Test 9: backpressure: true in handshake documents…
nhachicha Apr 28, 2026
ba29122
JAVA-5950 Update Transactions Convenient API with exponential backoff…
nhachicha May 1, 2026
d8d1225
JAVA-5949 preserve connection pool on backpressure errors when establ…
nhachicha May 8, 2026
f05af7d
JAVA-6174 Fix sdam eventType to assert serverDescriptionChangedEvent …
nhachicha May 22, 2026
37f39aa
JAVA-6194 Add MongoSocksProxyException for CMAP backpressure labeling…
nhachicha Jun 1, 2026
bd019de
Improve the label in the `withTransaction` method (#1994)
stIncMale Jun 4, 2026
8827cf8
Remove skips for enableOverloadRetargeting. (#1995)
vbabanin Jun 4, 2026
77d39fc
Refactor `MixedBulkWriteOperation` to simplify retry logic there (#1989)
stIncMale Jun 19, 2026
7bc2041
Introduce the `RetryPolicy` abstraction (#2004)
stIncMale Jul 29, 2026
6b4c8a5
Fix tests after `backpressure` rebase
stIncMale Aug 18, 2026
326f874
Introduce necessary executors and implement `sleepAsync` (#2040)
stIncMale Aug 18, 2026
78d3180
Implement the overload retry policy for commands that are read/write …
stIncMale Aug 22, 2026
8366833
Add overload retry policy for runCommand operations (#2044)
vbabanin Aug 27, 2026
441e8f2
Adds overload retry for cursor getMore (#2046)
vbabanin Sep 2, 2026
e1774fd
Add overload retry for non-retryable commands (#2048)
vbabanin Sep 10, 2026
52aad5e
Replace error label string literals with constants(#2055)
vbabanin Sep 15, 2026
ad16f81
Add code design rules for AI (#2028)
stIncMale Sep 16, 2026
117b37c
Update client and server @since labels to 5.12 and 9 for server (#2057)
strogiyotec Sep 17, 2026
0436355
Add baseBackoffMS support (#2052)
vbabanin Sep 17, 2026
43d09eb
Introduce temporary fallback scheduler into `DefaultAsyncClientExecut…
stIncMale Sep 17, 2026
c1415d5
Remove a `TODO-BACKPRESSURE` comment because it is no longer relevant
stIncMale Sep 17, 2026
7c5812d
Update the `specifications` submodule from d4d0cdf to 92b3c0b to matc…
stIncMale Sep 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
26 changes: 26 additions & 0 deletions .agents/references/code-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: code-design
description: Design rules for implementation code in the MongoDB Java Driver. Use when adding or modifying an internal program element, or changing the implementation of a public API program element.
---
# Code Design

## Access Modifiers

- Use the most restrictive access modifier that is sufficient for now.
- If there is an internal program element suitable for the task but not accessible, relax its access modifier
to the least permissive one that makes it accessible,
unless it contradicts the intent expressed in the documentation of the program element in question.
Be careful not to make the program element part of the public API accidentally.
- When access is relaxed only for tests, annotate the program element with `VisibleForTesting`.


## Executors

- Avoid instantiating new executors/threads. Consider using the existing `CommonExecutor` or `AsyncClientExecutor`.
- If a new executor/thread is unavoidable, prefer instantiating a new executor with a single thread over a bare thread.
It should be created and managed either by `CommonExecutor`, `AsyncClientExecutor`,
or a class whose instance is accessible via them. This may require changing their design, implementation, documentation.
- When instantiating an executor, prefer the `MongoThreadPoolExecutor` and `MongoScheduledThreadPoolExecutor` implementations.
- Must use daemon threads, see `DaemonThreadFactory`.
- Any task executed, submitted, or scheduled via an executor must not allow an `Exception` to be propagated;
`Error`s should generally not be caught, but if they are, they must still be propagated.
4 changes: 4 additions & 0 deletions .evergreen/.evg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,10 @@ axes:
display_name: "8.0"
variables:
VERSION: "8.0"
- id: "9.0"
display_name: "9.0"
variables:
VERSION: "9.0"
# 8.2 is used solely for Windows testing. MongoDB 8.0 binaries are affected by SERVER-116018 on Windows,
# and the fix is only available starting from 8.2.
- id: "8.2"
Expand Down
7 changes: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ The default branch is `main` (not `master`). Always use `main` when comparing, d
- Preserve existing comments — only remove if provably incorrect
- No rewrites without explicit permission
- When stuck or uncertain: stop, explain, propose alternatives, ask
- When authoring or reviewing changes: consult the relevant `.agents/references/` file for each area the changes touch

## Build

Expand Down Expand Up @@ -74,6 +75,12 @@ public API classes must be thread-safe unless annotated otherwise.
See [`.agents/references/api-design`](.agents/references/api-design.md) for stability annotations,
design principles, and the full nullability and thread safety conventions.

## Code Design

Applies to implementation code — internal packages, method bodies, and private or package-access program elements.

See [`.agents/references/code-design`](.agents/references/code-design.md) for the rules.

## Do Not Modify Without Human Approval

- Wire protocol / authentication handshakes (`com.mongodb.internal.connection`)
Expand Down
2 changes: 1 addition & 1 deletion config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@

<module name="MethodLength"/>
<module name="ParameterNumber">
<property name="max" value="12"/>
<property name="max" value="13"/>
</module>


Expand Down
37 changes: 34 additions & 3 deletions config/spotbugs/exclude.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
-->

<!--
Every time you add an entry to this file, you must specify its MongoDB status and SpotBugs rank.

To determine the rank of a newly-detected bug that you would like to exclude,
run spotbugsMain task with xml.enabled, then examine the XML report in
<module>/build/reports/spotbugs/main.xml, where the rankings are
run the `spotbugsMain` Gradle task with `xmlReports.enabled`
(example: `./gradlew spotbugsMain -PxmlReports.enabled=true`),
then examine the XML report in
`<module>/build/reports/spotbugs/main.xml`, where the rankings are
included as part of the report, e.g.

<BugInstance type="PA_PUBLIC_PRIMITIVE_ATTRIBUTE" priority="2" rank="16" ...
Expand Down Expand Up @@ -284,6 +288,16 @@
</Match>

<!-- Void method returning null but @NotNull API -->
<Match>
<Class name="com.mongodb.internal.operation.CreateCollectionOperation"/>
<Method name="execute"/>
<Bug pattern="NP_NONNULL_RETURN_VIOLATION"/>
</Match>
<Match>
<Class name="com.mongodb.internal.operation.DropCollectionOperation"/>
<Method name="execute"/>
<Bug pattern="NP_NONNULL_RETURN_VIOLATION"/>
</Match>
<Match>
<Class name="com.mongodb.internal.operation.DropIndexOperation"/>
<Method name="execute"/>
Expand All @@ -295,5 +309,22 @@
<Class name="com.mongodb.internal.crypt.capi.CAPI$cstring"/>
<Bug pattern="NM_CLASS_NAMING_CONVENTION"/>
</Match>

<Match>
<!-- MongoDB status: "False Positive", SpotBugs rank: 18 -->
<!-- The second parameter of the Java SE API method we override is not annotated,
but we know the argument may be `null`, so we annotate the corresponding parameter
in the overriding method with `@Nullable`. -->
<Class name="com.mongodb.internal.thread.MongoScheduledThreadPoolExecutor"/>
<Method name="afterExecute"/>
<Bug pattern="NP_METHOD_PARAMETER_TIGHTENS_ANNOTATION"/>
</Match>
<Match>
<!-- MongoDB status: "False Positive", SpotBugs rank: 18 -->
<!-- The second parameter of the Java SE API method we override is not annotated,
but we know the argument may be `null`, so we annotate the corresponding parameter
in the overriding method with `@Nullable`. -->
<Class name="com.mongodb.internal.thread.MongoThreadPoolExecutor"/>
<Method name="afterExecute"/>
<Bug pattern="NP_METHOD_PARAMETER_TIGHTENS_ANNOTATION"/>
</Match>
</FindBugsFilter>
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@

package com.mongodb.benchmark.benchmarks;

import org.bson.BsonArray;import org.bson.BsonDocument;
import org.bson.BsonArray;
import org.bson.BsonDocument;
import org.bson.RawBsonDocument;
import org.bson.codecs.BsonDocumentCodec;

Expand Down Expand Up @@ -52,4 +53,4 @@ public void setUp() throws IOException {
public int getBytesPerRun() {
return documentBytes.length * NUM_INTERNAL_ITERATIONS;
}
}
}
77 changes: 66 additions & 11 deletions driver-core/src/main/com/mongodb/ConnectionString.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.mongodb;

import com.mongodb.annotations.Alpha;
import com.mongodb.annotations.Beta;
import com.mongodb.annotations.Reason;
import com.mongodb.connection.ClusterSettings;
import com.mongodb.connection.ConnectionPoolSettings;
Expand Down Expand Up @@ -264,14 +265,20 @@
* <p>SRV configuration:</p>
* <ul>
* <li>{@code srvServiceName=string}: The SRV service name. See {@link ClusterSettings#getSrvServiceName()} for details.</li>
* <li>{@code srvMaxHosts=number}: The maximum number of hosts from the SRV record to connect to.</li>
* <li>{@code srvMaxHosts=n}: The maximum number of hosts from the SRV record to connect to.</li>
* </ul>
* <p>General configuration:</p>
* <ul>
* <li>{@code retryWrites=true|false}. If true the driver will retry supported write operations if they fail due to a network error.
* 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 retryWrites=true|false}: Whether attempts to execute write commands should be retried if they fail due to a retryable error.
* Defaults to true. See also {@code maxAdaptiveRetries}.</li>
* <li>{@code retryReads=true|false}: Whether attempts to execute read commands should be retried if they fail due to a retryable error.
* Defaults to true. See also {@code maxAdaptiveRetries}.</li>
* <li>{@code maxAdaptiveRetries=n}: This is {@linkplain Beta Beta API}.
* The maximum number of retry attempts when encountering a retryable overload error.
* See {@link MongoClientSettings.Builder#maxAdaptiveRetries(Integer)} for more information.</li>
* <li>{@code enableOverloadRetargeting=true|false}: This is {@linkplain Beta Beta API}.
* Whether to enable overload retargeting. Defaults to false.
* See {@link MongoClientSettings.Builder#enableOverloadRetargeting(boolean)} for more information.</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 +315,8 @@ public class ConnectionString {
private WriteConcern writeConcern;
private Boolean retryWrites;
private Boolean retryReads;
private Integer maxAdaptiveRetries;
private Boolean enableOverloadRetargeting;
private ReadConcern readConcern;

private Integer minConnectionPoolSize;
Expand Down Expand Up @@ -558,6 +567,8 @@ 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("maxadaptiveretries");
GENERAL_OPTIONS_KEYS.add("enableoverloadretargeting");

GENERAL_OPTIONS_KEYS.add("appname");

Expand Down Expand Up @@ -706,6 +717,15 @@ private void translateOptions(final Map<String, List<String>> optionsMap) {
case "retryreads":
retryReads = parseBoolean(value, "retryreads");
break;
case "maxadaptiveretries":
maxAdaptiveRetries = parseInteger(value, "maxadaptiveretries");
if (maxAdaptiveRetries < 0) {
throw new IllegalArgumentException("maxAdaptiveRetries must be >= 0");
}
break;
case "enableoverloadretargeting":
enableOverloadRetargeting = parseBoolean(value, "enableoverloadretargeting");
break;
case "uuidrepresentation":
uuidRepresentation = createUuidRepresentation(value);
break;
Expand Down Expand Up @@ -1455,13 +1475,15 @@ public WriteConcern getWriteConcern() {
}

/**
* <p>Gets whether writes should be retried if they fail due to a network error</p>
*
* Gets whether attempts to execute write commands should be retried if they fail due to a retryable error.
* See {@link MongoClientSettings.Builder#retryWrites(boolean)} for more information.
* <p>
* The name of this method differs from others in this class so as not to conflict with the now removed
* getRetryWrites() method, which returned a primitive {@code boolean} value, and didn't allow callers to differentiate
* between a false value and an unset value.
*
* @return the retryWrites value, or null if unset
* @return the {@code retryWrites} value, or {@code null} if unset
* @see #getMaxAdaptiveRetries()
* @since 3.9
* @mongodb.server.release 3.6
*/
Expand All @@ -1471,9 +1493,11 @@ public Boolean getRetryWritesValue() {
}

/**
* <p>Gets whether reads should be retried if they fail due to a network error</p>
* Gets whether attempts to execute read commands should be retried if they fail due to a retryable error.
* See {@link MongoClientSettings.Builder#retryReads(boolean)} for more information.
*
* @return the retryWrites value
* @return the {@code retryReads} value, or {@code null} if unset
* @see #getMaxAdaptiveRetries()
* @since 3.11
* @mongodb.server.release 3.6
*/
Expand All @@ -1482,6 +1506,35 @@ public Boolean getRetryReads() {
return retryReads;
}

/**
* Gets the maximum number of retry attempts when encountering a retryable overload error.
* See {@link MongoClientSettings.Builder#maxAdaptiveRetries(Integer)} for more information.
*
* @return The {@code maxAdaptiveRetries} value, or {@code null} if unset.
* @since 5.12
* @mongodb.server.release 9.0
*/
@Beta(Reason.CLIENT)
@Nullable
public Integer getMaxAdaptiveRetries() {
return maxAdaptiveRetries;
}

/**
* Gets whether overload retargeting is enabled.
* See {@link MongoClientSettings.Builder#enableOverloadRetargeting(boolean)} for more information.
*
* @return the enableOverloadRetargeting value, or null if not set
* @see MongoClientSettings.Builder#enableOverloadRetargeting(boolean)
* @since 5.12
* @mongodb.server.release 9.0
*/
@Beta(Reason.CLIENT)
@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 +1848,8 @@ public boolean equals(final Object o) {
&& Objects.equals(writeConcern, that.writeConcern)
&& Objects.equals(retryWrites, that.retryWrites)
&& Objects.equals(retryReads, that.retryReads)
&& Objects.equals(maxAdaptiveRetries, that.maxAdaptiveRetries)
&& 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,7 +1881,7 @@ 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,
writeConcern, retryWrites, retryReads, maxAdaptiveRetries, enableOverloadRetargeting, readConcern, minConnectionPoolSize, maxConnectionPoolSize, maxWaitTime,
maxConnectionIdleTime, maxConnectionLifeTime, maxConnecting, connectTimeout, timeout, socketTimeout, sslEnabled,
sslInvalidHostnameAllowed, requiredReplicaSetName, serverSelectionTimeout, localThreshold, heartbeatFrequency,
serverMonitoringMode, applicationName, compressorList, uuidRepresentation, srvServiceName, srvMaxHosts, proxyHost,
Expand Down
Loading
Loading