From 8ff41337f9b877179537bfb4d304eec1b2ef3c4b Mon Sep 17 00:00:00 2001 From: Slav Babanin Date: Tue, 8 Sep 2026 17:36:29 -0700 Subject: [PATCH 1/8] JAVA-6238 use retry number as backoff exponent --- .../main/com/mongodb/internal/time/ExponentialBackoff.java | 2 +- .../com/mongodb/internal/time/ExponentialBackoffTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/driver-core/src/main/com/mongodb/internal/time/ExponentialBackoff.java b/driver-core/src/main/com/mongodb/internal/time/ExponentialBackoff.java index be2813c5d15..4b4c5f1eaf7 100644 --- a/driver-core/src/main/com/mongodb/internal/time/ExponentialBackoff.java +++ b/driver-core/src/main/com/mongodb/internal/time/ExponentialBackoff.java @@ -70,7 +70,7 @@ private static long calculateBackoffMs(final double baseMs, final double maxMs, ? testJitterSupplier.getAsDouble() : ThreadLocalRandom.current().nextDouble(); return Math.round(jitter * Math.min( - baseMs * Math.pow(growth, attemptNumber - 1), + baseMs * Math.pow(growth, attemptNumber), maxMs)); } diff --git a/driver-core/src/test/unit/com/mongodb/internal/time/ExponentialBackoffTest.java b/driver-core/src/test/unit/com/mongodb/internal/time/ExponentialBackoffTest.java index 504a9840e73..f36d4df5180 100644 --- a/driver-core/src/test/unit/com/mongodb/internal/time/ExponentialBackoffTest.java +++ b/driver-core/src/test/unit/com/mongodb/internal/time/ExponentialBackoffTest.java @@ -28,8 +28,8 @@ class ExponentialBackoffTest { * Expected {@linkplain ExponentialBackoff#calculateTransactionBackoffMs(int) backoffs} with 1.0 as * {@link ExponentialBackoff#setTestJitterSupplier(DoubleSupplier) jitter}. */ - private static final double[] EXPECTED_BACKOFFS_MAX_VALUES = {5.0, 7.5, 11.25, 16.875, 25.3125, 37.96875, 56.953125, 85.4296875, 128.14453125, - 192.21679688, 288.32519531, 432.48779297, 500.0}; + private static final double[] EXPECTED_BACKOFFS_MAX_VALUES = {7.5, 11.25, 16.875, 25.3125, 37.96875, 56.953125, 85.4296875, 128.14453125, + 192.21679688, 288.32519531, 432.48779297, 500.0, 500.0}; @Test void testCalculateTransactionBackoffMs() { From c43bfac374e9cff388a1b3ce366da041468a3bfa Mon Sep 17 00:00:00 2001 From: Slav Babanin Date: Tue, 8 Sep 2026 18:47:49 -0700 Subject: [PATCH 2/8] JAVA-6255 correct withTransaction backoff test sum to 2.3s --- .../functional/com/mongodb/client/WithTransactionProseTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver-sync/src/test/functional/com/mongodb/client/WithTransactionProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/WithTransactionProseTest.java index 6d2b928e8ec..d726adfa9b3 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/WithTransactionProseTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/WithTransactionProseTest.java @@ -235,7 +235,7 @@ public void testRetryBackoffIsEnforced() throws InterruptedException { long noBackoffTimeMs = measureTransactionLatencyMs(0.0); long withBackoffTimeMs = measureTransactionLatencyMs(1.0); - long sumOfBackoffsMs = 1800; + long sumOfBackoffsMs = 2300; long toleranceMs = 500; long actualDifferenceMs = Math.abs(withBackoffTimeMs - (noBackoffTimeMs + sumOfBackoffsMs)); From 018a34cd70c5bb761cb9030bb899c3cc8c9604f2 Mon Sep 17 00:00:00 2001 From: Slav Babanin Date: Tue, 8 Sep 2026 20:56:45 -0700 Subject: [PATCH 3/8] JAVA-6238 update overload backoff prose test to 0.6s sum per new formula --- .../functional/com/mongodb/client/BackpressureProseTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/driver-sync/src/test/functional/com/mongodb/client/BackpressureProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/BackpressureProseTest.java index bb566ed2fe4..542dafcf022 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/BackpressureProseTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/BackpressureProseTest.java @@ -117,8 +117,8 @@ void operationRetryUsesExponentialBackoff() throws InterruptedException { MongoCollection collection = dropAndGetCollection("operationRetryUsesExponentialBackoff", client); long noBackoffTimeMillis = measureFailedInsertDuration(collection, false).toMillis(); long withBackoffTimeMillis = measureFailedInsertDuration(collection, true).toMillis(); - long expectedMaxVarianceMillis = 300; - long maxTotalBackoffMillis = 300; + long expectedMaxVarianceMillis = 600; + long maxTotalBackoffMillis = 600; long actualAbsDiffMillis = Math.abs(withBackoffTimeMillis - (noBackoffTimeMillis + maxTotalBackoffMillis)); assertTrue(actualAbsDiffMillis < expectedMaxVarianceMillis, format("Expected actualAbsDiffMillis < %d ms, but was %d ms (|%d ms - (%d ms + %d ms)|)", From a8ed3be5cf9bc25da6a232da774ba9d4a3a6c41b Mon Sep 17 00:00:00 2001 From: Slav Babanin Date: Wed, 9 Sep 2026 12:44:34 -0700 Subject: [PATCH 4/8] JAVA-6238 send backpressure: "2" in handshake --- .../InternalStreamConnectionInitializer.java | 2 +- ...alStreamConnectionInitializerSpecification.groovy | 8 ++++---- .../client/AbstractClientMetadataProseTest.java | 12 +++++------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnectionInitializer.java b/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnectionInitializer.java index 36f6688cb0e..1af994635f9 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnectionInitializer.java +++ b/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnectionInitializer.java @@ -173,7 +173,7 @@ private InternalConnectionInitializationDescription createInitializationDescript private BsonDocument createHelloCommand(final Authenticator authenticator, final InternalConnection connection) { BsonDocument helloCommandDocument = new BsonDocument(getHandshakeCommandName(), new BsonInt32(1)) .append("helloOk", BsonBoolean.TRUE) - .append("backpressure", BsonBoolean.TRUE); + .append("backpressure", new BsonString("2")); if (clientMetadataDocument != null) { helloCommandDocument.append("client", clientMetadataDocument); } diff --git a/driver-core/src/test/unit/com/mongodb/internal/connection/InternalStreamConnectionInitializerSpecification.groovy b/driver-core/src/test/unit/com/mongodb/internal/connection/InternalStreamConnectionInitializerSpecification.groovy index d3f05ea8b49..4a4b1c0f231 100644 --- a/driver-core/src/test/unit/com/mongodb/internal/connection/InternalStreamConnectionInitializerSpecification.groovy +++ b/driver-core/src/test/unit/com/mongodb/internal/connection/InternalStreamConnectionInitializerSpecification.groovy @@ -201,7 +201,7 @@ class InternalStreamConnectionInitializerSpecification extends Specification { def initializer = new InternalStreamConnectionInitializer(SINGLE, null, clientMetadataDocument, [], null) def expectedHelloCommandDocument = new BsonDocument(LEGACY_HELLO, new BsonInt32(1)) .append('helloOk', BsonBoolean.TRUE) - .append('backpressure', BsonBoolean.TRUE) + .append('backpressure', new BsonString('2')) .append('\$db', new BsonString('admin')) if (clientMetadataDocument != null) { expectedHelloCommandDocument.append('client', clientMetadataDocument) @@ -234,7 +234,7 @@ class InternalStreamConnectionInitializerSpecification extends Specification { def initializer = new InternalStreamConnectionInitializer(SINGLE, null, null, compressors, null) def expectedHelloCommandDocument = new BsonDocument(LEGACY_HELLO, new BsonInt32(1)) .append('helloOk', BsonBoolean.TRUE) - .append('backpressure', BsonBoolean.TRUE) + .append('backpressure', new BsonString('2')) .append('\$db', new BsonString('admin')) def compressionArray = new BsonArray() @@ -405,7 +405,7 @@ class InternalStreamConnectionInitializerSpecification extends Specification { ((SpeculativeAuthenticator) authenticator).getSpeculativeAuthenticateResponse() == null ((SpeculativeAuthenticator) authenticator) .createSpeculativeAuthenticateCommand(internalConnection) == null - BsonDocument.parse("{$LEGACY_HELLO: 1, helloOk: true, backpressure: true, '\$db': 'admin'}") == + BsonDocument.parse("{$LEGACY_HELLO: 1, helloOk: true, backpressure: \"2\", '\$db': 'admin'}") == decodeCommand(internalConnection.getSent()[0]) where: @@ -503,7 +503,7 @@ class InternalStreamConnectionInitializerSpecification extends Specification { def createHelloCommand(final String firstClientChallenge, final String mechanism, final boolean hasSaslSupportedMechs) { - String hello = "{$LEGACY_HELLO: 1, helloOk: true, backpressure: true, " + + String hello = "{$LEGACY_HELLO: 1, helloOk: true, backpressure: \"2\", " + (hasSaslSupportedMechs ? 'saslSupportedMechs: "database.user", ' : '') + (mechanism == 'MONGODB-X509' ? 'speculativeAuthenticate: { authenticate: 1, ' + diff --git a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientMetadataProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientMetadataProseTest.java index 320f79e54b2..865b4492294 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientMetadataProseTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientMetadataProseTest.java @@ -24,8 +24,8 @@ import com.mongodb.internal.connection.TestCommandListener; import com.mongodb.internal.connection.TestConnectionPoolListener; import com.mongodb.lang.Nullable; -import org.bson.BsonBoolean; import org.bson.BsonDocument; +import org.bson.BsonString; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -335,9 +335,9 @@ void testEmptyStringsAreConsideredUnsetWhenAppendingMetadataIdenticalToInitialMe } } - @DisplayName("Test 9: Handshake documents include backpressure: true") + @DisplayName("Test 9: Handshake documents include backpressure: \"2\"") @Test - void testHandshakeDocumentsIncludeBackpressureTrue() { + void testHandshakeDocumentsIncludeBackpressureTwo() { try (MongoClient mongoClient = createMongoClient(null, getMongoClientSettings())) { commandListener.reset(); mongoClient.getDatabase("admin").runCommand(BsonDocument.parse("{ping: 1}")); @@ -346,10 +346,8 @@ void testHandshakeDocumentsIncludeBackpressureTrue() { assertFalse(handshakeEvents.isEmpty(), "Expected at least one handshake document to be captured"); for (CommandStartedEvent event : handshakeEvents) { BsonDocument helloCommand = event.getCommand(); - assertTrue(helloCommand.containsKey("backpressure"), - "Handshake document is missing 'backpressure' field"); - assertEquals(BsonBoolean.TRUE, helloCommand.getBoolean("backpressure"), - "Handshake document 'backpressure' field is not true"); + assertEquals(new BsonString("2"), helloCommand.get("backpressure"), + "Handshake document 'backpressure' field is not the string \"2\""); } } } From a79ba822b59430bb057db261fb8cea2712c41074 Mon Sep 17 00:00:00 2001 From: Slav Babanin Date: Wed, 9 Sep 2026 15:27:08 -0700 Subject: [PATCH 5/8] JAVA-6238 support server-supplied baseBackoffMS override for overload backoff --- .../internal/operation/SpecRetryPolicy.java | 23 ++++++++- .../internal/time/ExponentialBackoff.java | 16 ++++++- .../internal/time/ExponentialBackoffTest.java | 48 +++++++++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/driver-core/src/main/com/mongodb/internal/operation/SpecRetryPolicy.java b/driver-core/src/main/com/mongodb/internal/operation/SpecRetryPolicy.java index 650423c7d5c..ffb738b877d 100644 --- a/driver-core/src/main/com/mongodb/internal/operation/SpecRetryPolicy.java +++ b/driver-core/src/main/com/mongodb/internal/operation/SpecRetryPolicy.java @@ -16,6 +16,7 @@ package com.mongodb.internal.operation; import com.mongodb.MongoClientSettings; +import com.mongodb.MongoCommandException; import com.mongodb.MongoConnectionPoolClearedException; import com.mongodb.MongoException; import com.mongodb.MongoOperationTimeoutException; @@ -33,6 +34,9 @@ import com.mongodb.internal.time.ExponentialBackoff; import com.mongodb.lang.Nullable; +import org.bson.BsonDocument; +import org.bson.BsonValue; + import java.time.Duration; import java.util.EnumMap; import java.util.EnumSet; @@ -285,11 +289,28 @@ private static Duration calculateOverloadBackoff(final Throwable attemptFailedRe assertFalse(attemptFailedResult instanceof OperationHelper.ResourceSupplierInternalException); if (attemptFailedResult instanceof MongoException && ((MongoException) attemptFailedResult).hasErrorLabel(SYSTEM_OVERLOADED_ERROR_LABEL)) { - return ExponentialBackoff.calculateOverloadBackoff(immediateNextAttempt); + return ExponentialBackoff.calculateOverloadBackoff(immediateNextAttempt, extractBaseBackoffMs(attemptFailedResult)); } return Duration.ZERO; } + @Nullable + private static Long extractBaseBackoffMs(final Throwable attemptFailedResult) { + if (!(attemptFailedResult instanceof MongoCommandException)) { + return null; + } + BsonDocument response = ((MongoCommandException) attemptFailedResult).getResponse(); + if (!response.containsKey("baseBackoffMS")) { + return null; + } + BsonValue value = response.get("baseBackoffMS"); + if (!value.isNumber()) { + return null; + } + long parsed = value.asNumber().longValue(); + return parsed > 0 ? parsed : null; + } + private static int maxAttempts(final int maxRetries) { if (maxRetries == INFINITE_ATTEMPTS) { return INFINITE_ATTEMPTS; diff --git a/driver-core/src/main/com/mongodb/internal/time/ExponentialBackoff.java b/driver-core/src/main/com/mongodb/internal/time/ExponentialBackoff.java index 4b4c5f1eaf7..78584778a91 100644 --- a/driver-core/src/main/com/mongodb/internal/time/ExponentialBackoff.java +++ b/driver-core/src/main/com/mongodb/internal/time/ExponentialBackoff.java @@ -18,6 +18,7 @@ import com.mongodb.internal.VisibleForTesting; import com.mongodb.internal.async.function.RetryControl; +import com.mongodb.lang.Nullable; import java.time.Duration; import java.util.concurrent.ThreadLocalRandom; @@ -58,7 +59,20 @@ public static long calculateTransactionBackoffMs(final int attemptNumber) { * See {@link #calculateTransactionBackoffMs(int)} for more details. */ public static Duration calculateOverloadBackoff(final int attemptNumber) { - return Duration.ofMillis(calculateBackoffMs(100, 10000, 2, attemptNumber)); + return calculateOverloadBackoff(attemptNumber, null); + } + + /** + * Calculate the backoff for command retries caused by + * {@linkplain com.mongodb.MongoException#SYSTEM_OVERLOADED_ERROR_LABEL overload}, + * optionally using a server-supplied {@code baseBackoffMs} in place of the 100ms default. + * A {@code null} or non-positive {@code baseBackoffMs} falls back to the default. + * + * @param baseBackoffMs The server-supplied base backoff in milliseconds, or {@code null}. + */ + public static Duration calculateOverloadBackoff(final int attemptNumber, @Nullable final Long baseBackoffMs) { + double baseMs = baseBackoffMs != null && baseBackoffMs > 0 ? baseBackoffMs : 100; + return Duration.ofMillis(calculateBackoffMs(baseMs, 10000, 2, attemptNumber)); } /** diff --git a/driver-core/src/test/unit/com/mongodb/internal/time/ExponentialBackoffTest.java b/driver-core/src/test/unit/com/mongodb/internal/time/ExponentialBackoffTest.java index f36d4df5180..d4686e05827 100644 --- a/driver-core/src/test/unit/com/mongodb/internal/time/ExponentialBackoffTest.java +++ b/driver-core/src/test/unit/com/mongodb/internal/time/ExponentialBackoffTest.java @@ -79,4 +79,52 @@ void testCalculateTransactionBackoffMsWithJitterZero() { ExponentialBackoff.clearTestJitterSupplier(); } } + + @Test + void testCalculateOverloadBackoffUsesDefaultBaseWhenOverrideAbsent() { + ExponentialBackoff.setTestJitterSupplier(() -> 1.0); + try { + // 100 * 2^1 = 200, 100 * 2^2 = 400 + assertEquals(200L, ExponentialBackoff.calculateOverloadBackoff(1).toMillis()); + assertEquals(400L, ExponentialBackoff.calculateOverloadBackoff(2).toMillis()); + // null override == default + assertEquals(200L, ExponentialBackoff.calculateOverloadBackoff(1, null).toMillis()); + } finally { + ExponentialBackoff.clearTestJitterSupplier(); + } + } + + @Test + void testCalculateOverloadBackoffUsesServerBaseBackoffMsWhenPositive() { + ExponentialBackoff.setTestJitterSupplier(() -> 1.0); + try { + // 50 * 2^1 = 100, 50 * 2^2 = 200 + assertEquals(100L, ExponentialBackoff.calculateOverloadBackoff(1, 50L).toMillis()); + assertEquals(200L, ExponentialBackoff.calculateOverloadBackoff(2, 50L).toMillis()); + } finally { + ExponentialBackoff.clearTestJitterSupplier(); + } + } + + @Test + void testCalculateOverloadBackoffIgnoresNonPositiveOverride() { + ExponentialBackoff.setTestJitterSupplier(() -> 1.0); + try { + assertEquals(200L, ExponentialBackoff.calculateOverloadBackoff(1, 0L).toMillis()); + assertEquals(200L, ExponentialBackoff.calculateOverloadBackoff(1, -10L).toMillis()); + } finally { + ExponentialBackoff.clearTestJitterSupplier(); + } + } + + @Test + void testCalculateOverloadBackoffRespectsMaxCapWithLargeBaseBackoffMs() { + ExponentialBackoff.setTestJitterSupplier(() -> 1.0); + try { + // base 20000 * 2^1 = 40000 -> capped at 10000 + assertEquals(10000L, ExponentialBackoff.calculateOverloadBackoff(1, 20000L).toMillis()); + } finally { + ExponentialBackoff.clearTestJitterSupplier(); + } + } } From 26218da36d17420d7ffdc1029e74908d85f078d4 Mon Sep 17 00:00:00 2001 From: Slav Babanin Date: Wed, 9 Sep 2026 16:51:29 -0700 Subject: [PATCH 6/8] JAVA-6238 add baseBackoffMS override prose test (Test 5) --- .../mongodb/client/BackpressureProseTest.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/driver-sync/src/test/functional/com/mongodb/client/BackpressureProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/BackpressureProseTest.java index 542dafcf022..07bdc7f4579 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/BackpressureProseTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/BackpressureProseTest.java @@ -137,6 +137,57 @@ private static Duration measureFailedInsertDuration(final MongoCollection collection) { + StartTime startTime = StartTime.now(); + assertThrows(MongoServerException.class, () -> collection.insertOne(Document.parse("{a: 1}"))); + return startTime.elapsed(); + } + + /** + * + * Test 5: Overload Errors with baseBackoffMS override base backoff. + */ + @Test + void overloadErrorsWithBaseBackoffMsOverrideBaseBackoff() throws InterruptedException { + assumeTrue(serverVersionAtLeast(9, 0)); + BsonDocument configureFailPoint = BsonDocument.parse( + "{\n" + + " configureFailPoint: 'failCommand',\n" + + " mode: 'alwaysOn',\n" + + " data: {\n" + + " failCommands: ['insert'],\n" + + " errorCode: 462,\n" + + " errorLabels: ['" + SYSTEM_OVERLOADED_ERROR_LABEL + "', '" + RETRYABLE_ERROR_LABEL + "']\n" + + " }\n" + + "}\n"); + try (MongoClient client = createClient(getMongoClientSettings()); + FailPoint ignored = FailPoint.enable(configureFailPoint, getPrimary())) { + MongoCollection collection = dropAndGetCollection("overloadErrorsWithBaseBackoffMsOverrideBaseBackoff", client); + + ExponentialBackoff.setTestJitterSupplier(() -> 1); + try { + long exponentialBackoffTimeMs = measureFailedInsertDuration(collection).toMillis(); + + client.getDatabase("admin").runCommand(Document.parse("{setParameter: 1, externalClientBaseBackoffMS: 50}")); + long withBaseBackoffMsTimeMs; + try { + withBaseBackoffMsTimeMs = measureFailedInsertDuration(collection).toMillis(); + } finally { + client.getDatabase("admin").runCommand(Document.parse("{setParameter: 1, externalClientBaseBackoffMS: 0}")); + } + + assertTrue(exponentialBackoffTimeMs >= 600, + format("Expected default-backoff run >= 600 ms, was %d ms", exponentialBackoffTimeMs)); + assertTrue(withBaseBackoffMsTimeMs >= 300, + format("Expected baseBackoffMS=50 run >= 300 ms, was %d ms", withBaseBackoffMsTimeMs)); + assertTrue(withBaseBackoffMsTimeMs < 600, + format("Expected baseBackoffMS=50 run < 600 ms, was %d ms", withBaseBackoffMsTimeMs)); + } finally { + ExponentialBackoff.clearTestJitterSupplier(); + } + } + } + /** * * Test 3: Overload Errors are Retried a Maximum of {@code MAX_RETRIES} times. From e079ed40107d4bf1de6f5c4346b4c6de4d4de3df Mon Sep 17 00:00:00 2001 From: Slav Babanin Date: Wed, 9 Sep 2026 18:10:39 -0700 Subject: [PATCH 7/8] JAVA-6238 add MongoDB 9.0 to Evergreen version matrix Add a 9.0 entry to the version axis and include 9.0 in all test matrix variants that currently test against 8.0, mirroring the Python and Node drivers. This gives the backpressure baseBackoffMS override prose test (Test 5, gated on serverVersionAtLeast(9, 0)) a pinned CI variant to run against. --- .evergreen/.evg.yml | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/.evergreen/.evg.yml b/.evergreen/.evg.yml index 1cc9508af3f..56960d41a76 100644 --- a/.evergreen/.evg.yml +++ b/.evergreen/.evg.yml @@ -1740,6 +1740,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" @@ -2341,7 +2345,7 @@ buildvariants: # - matrix_name: "tests-zlib-compression" - matrix_spec: { compressor: "zlib", auth: "noauth", ssl: "nossl", jdk: "jdk8", version: [ "4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "latest" ], topology: "standalone", os: "linux" } + matrix_spec: { compressor: "zlib", auth: "noauth", ssl: "nossl", jdk: "jdk8", version: [ "4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "9.0", "latest" ], topology: "standalone", os: "linux" } display_name: "${version} ${compressor} ${topology} ${auth} ${ssl} ${jdk} ${os} " tags: [ "tests-variant" ] tasks: @@ -2351,7 +2355,7 @@ buildvariants: - name: "test-legacy-task" - matrix_name: "tests-snappy-compression" - matrix_spec: { compressor: "snappy", auth: "noauth", ssl: "nossl", jdk: "jdk8", version: [ "4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "latest" ], topology: "standalone", os: "linux" } + matrix_spec: { compressor: "snappy", auth: "noauth", ssl: "nossl", jdk: "jdk8", version: [ "4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "9.0", "latest" ], topology: "standalone", os: "linux" } display_name: "${version} ${compressor} ${topology} ${auth} ${ssl} ${jdk} ${os} " tags: [ "tests-variant" ] tasks: @@ -2362,7 +2366,7 @@ buildvariants: - matrix_name: "tests-zstd-compression" matrix_spec: { compressor: "zstd", auth: "noauth", ssl: "nossl", jdk: "jdk8", - version: [ "4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "latest" ], + version: [ "4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "9.0", "latest" ], topology: "standalone", os: "linux" } display_name: "${version} ${compressor} ${topology} ${auth} ${ssl} ${jdk} ${os} " tags: [ "tests-variant" ] @@ -2380,7 +2384,7 @@ buildvariants: - name: "test-bson-and-crypt-task" - matrix_name: "tests-jdk8-unsecure" - matrix_spec: { auth: "noauth", ssl: "nossl", jdk: "jdk8", version: [ "4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "latest" ], + matrix_spec: { auth: "noauth", ssl: "nossl", jdk: "jdk8", version: [ "4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "9.0", "latest" ], topology: "*", os: "linux" } display_name: "${version} ${topology} ${auth} ${ssl} ${jdk} ${os} " tags: [ "tests-variant" ] @@ -2392,7 +2396,7 @@ buildvariants: - matrix_name: "tests-jdk-secure" matrix_spec: { auth: "auth", ssl: "ssl", jdk: [ "jdk8", "jdk17", "jdk21" ], - version: [ "4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "latest" ], + version: [ "4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "9.0", "latest" ], topology: "*", os: "linux" } display_name: "${version} ${topology} ${auth} ${ssl} ${jdk} ${os} " tags: [ "tests-variant" ] @@ -2429,7 +2433,7 @@ buildvariants: exec_timeout_secs: 7200 - matrix_name: "tests-require-api-version" - matrix_spec: { api-version: "required", auth: "auth", ssl: "nossl", jdk: [ "jdk21" ], version: [ "5.0", "6.0", "7.0", "8.0", "latest" ], + matrix_spec: { api-version: "required", auth: "auth", ssl: "nossl", jdk: [ "jdk21" ], version: [ "5.0", "6.0", "7.0", "8.0", "9.0", "latest" ], topology: "standalone", os: "linux" } display_name: "${version} ${topology} ${api-version} " tags: [ "tests-variant" ] @@ -2440,7 +2444,7 @@ buildvariants: - name: "test-legacy-task" - matrix_name: "tests-load-balancer-secure" - matrix_spec: { auth: "auth", ssl: "ssl", jdk: [ "jdk21" ], version: [ "5.0", "6.0", "7.0", "8.0", "latest" ], topology: "sharded-cluster", + matrix_spec: { auth: "auth", ssl: "ssl", jdk: [ "jdk21" ], version: [ "5.0", "6.0", "7.0", "8.0", "9.0", "latest" ], topology: "sharded-cluster", os: "ubuntu" } display_name: "Load Balancer ${version} ${auth} ${ssl} ${jdk} ${os}" tasks: @@ -2500,7 +2504,7 @@ buildvariants: - name: "gssapi-auth-test-task" - matrix_name: "aws-auth-test" - matrix_spec: { ssl: "nossl", jdk: [ "jdk8", "jdk17", "jdk21" ], version: [ "4.4", "5.0", "6.0", "7.0", "8.0", "latest" ], os: "ubuntu", + matrix_spec: { ssl: "nossl", jdk: [ "jdk8", "jdk17", "jdk21" ], version: [ "4.4", "5.0", "6.0", "7.0", "8.0", "9.0", "latest" ], os: "ubuntu", aws-credential-provider: "*" } display_name: "MONGODB-AWS Basic Auth test ${version} ${jdk} ${aws-credential-provider}" run_on: "ubuntu2204-small" @@ -2519,7 +2523,7 @@ buildvariants: - name: "aws-auth-test-with-web-identity-credentials-task" - matrix_name: "accept-api-version-2-test" - matrix_spec: { ssl: "nossl", auth: "noauth", jdk: "jdk21", version: [ "5.0", "6.0", "7.0", "8.0", "latest" ], topology: "standalone", + matrix_spec: { ssl: "nossl", auth: "noauth", jdk: "jdk21", version: [ "5.0", "6.0", "7.0", "8.0", "9.0", "latest" ], topology: "standalone", os: "linux" } display_name: "Accept API Version 2 ${version}" run_on: "ubuntu2204-small" @@ -2527,7 +2531,7 @@ buildvariants: - name: "accept-api-version-2-test-task" - matrix_name: "ocsp-test" - matrix_spec: { auth: "noauth", ssl: "ssl", jdk: "jdk21", version: [ "4.4", "5.0", "6.0", "7.0", "8.0", "latest" ], os: "ubuntu" } + matrix_spec: { auth: "noauth", ssl: "ssl", jdk: "jdk21", version: [ "4.4", "5.0", "6.0", "7.0", "8.0", "9.0", "latest" ], os: "ubuntu" } display_name: "OCSP test ${version} ${os}" tasks: - name: ".ocsp" @@ -2560,14 +2564,14 @@ buildvariants: - name: ".csfle-aws-from-environment" - matrix_name: "csfle-tests-with-mongocryptd" - matrix_spec: { os: "linux", version: [ "4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "latest" ], topology: [ "replicaset" ] } + matrix_spec: { os: "linux", version: [ "4.2", "4.4", "5.0", "6.0", "7.0", "8.0", "9.0", "latest" ], topology: [ "replicaset" ] } display_name: "CSFLE with mongocryptd: ${version}" tasks: - name: "csfle-tests-with-mongocryptd-task" - matrix_name: "csfle-tests-with-mongocryptd-windows" matrix_spec: { os: "windows", - version: [ "8.0", "latest" ], + version: [ "8.0", "9.0", "latest" ], topology: [ "replicaset" ] } display_name: "${os} CSFLE with mongocryptd: ${version}" tasks: From 1e202c4053abe639bba498c4fd980cc992a0a42b Mon Sep 17 00:00:00 2001 From: Slav Babanin Date: Wed, 9 Sep 2026 18:20:42 -0700 Subject: [PATCH 8/8] JAVA-6238 extract baseBackoffMS field name to a constant --- .../main/com/mongodb/internal/operation/SpecRetryPolicy.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/driver-core/src/main/com/mongodb/internal/operation/SpecRetryPolicy.java b/driver-core/src/main/com/mongodb/internal/operation/SpecRetryPolicy.java index ffb738b877d..6ba8421fff7 100644 --- a/driver-core/src/main/com/mongodb/internal/operation/SpecRetryPolicy.java +++ b/driver-core/src/main/com/mongodb/internal/operation/SpecRetryPolicy.java @@ -70,6 +70,7 @@ */ final class SpecRetryPolicy implements RetryPolicy { private static final int INFINITE_ATTEMPTS = Integer.MAX_VALUE; + private static final String BASE_BACKOFF_MS_FIELD = "baseBackoffMS"; private final IndividualPolicies policies; private int maxAttempts; @@ -300,10 +301,10 @@ private static Long extractBaseBackoffMs(final Throwable attemptFailedResult) { return null; } BsonDocument response = ((MongoCommandException) attemptFailedResult).getResponse(); - if (!response.containsKey("baseBackoffMS")) { + if (!response.containsKey(BASE_BACKOFF_MS_FIELD)) { return null; } - BsonValue value = response.get("baseBackoffMS"); + BsonValue value = response.get(BASE_BACKOFF_MS_FIELD); if (!value.isNumber()) { return null; }