diff --git a/driver-core/src/main/com/mongodb/internal/async/AsyncRunnable.java b/driver-core/src/main/com/mongodb/internal/async/AsyncRunnable.java index c108aeed0d..deeef6239c 100644 --- a/driver-core/src/main/com/mongodb/internal/async/AsyncRunnable.java +++ b/driver-core/src/main/com/mongodb/internal/async/AsyncRunnable.java @@ -16,7 +16,6 @@ package com.mongodb.internal.async; -import com.mongodb.internal.TimeoutContext; import com.mongodb.internal.async.function.AsyncCallbackLoop; import com.mongodb.internal.async.function.LoopState; import com.mongodb.internal.async.function.RetryState; @@ -39,7 +38,7 @@ * following "sync" method: * *
- * public T myMethod()
+ * public T myMethod() {
* method1();
* method2();
* }
@@ -47,7 +46,7 @@
* The async counterpart would be: * *
- * public void myMethodAsync(SingleResultCallback<T> callback)
+ * public void myMethodAsync(SingleResultCallback<T> callback) {
* beginAsync().thenRun(c -> {
* method1Async(c);
* }).thenRun(c -> {
@@ -229,11 +228,11 @@ default AsyncSupplier thenSupply(final AsyncSupplier supplier) {
* @return the composition of this, and the looping branch
* @see RetryingAsyncCallbackSupplier
*/
- default AsyncRunnable thenRunRetryingWhile(
- final TimeoutContext timeoutContext, final AsyncRunnable runnable, final Predicate shouldRetry) {
+ default AsyncRunnable thenRunRetryingWhile(final AsyncRunnable runnable, final Predicate shouldRetry) {
return thenRun(callback -> {
new RetryingAsyncCallbackSupplier(
- new RetryState(timeoutContext),
+ new RetryState(),
+ (previouslyChosenFailure, lastAttemptFailure) -> lastAttemptFailure,
(rs, lastAttemptFailure) -> shouldRetry.test(lastAttemptFailure),
// `finish` is required here instead of `unsafeFinish`
// because only `finish` meets the contract of
diff --git a/driver-core/src/main/com/mongodb/internal/async/function/RetryState.java b/driver-core/src/main/com/mongodb/internal/async/function/RetryState.java
index 3b8394dae1..b209035d7a 100644
--- a/driver-core/src/main/com/mongodb/internal/async/function/RetryState.java
+++ b/driver-core/src/main/com/mongodb/internal/async/function/RetryState.java
@@ -17,7 +17,6 @@
import com.mongodb.MongoOperationTimeoutException;
import com.mongodb.annotations.NotThreadSafe;
-import com.mongodb.internal.TimeoutContext;
import com.mongodb.internal.async.SingleResultCallback;
import com.mongodb.internal.async.function.LoopState.AttachmentKey;
import com.mongodb.lang.NonNull;
@@ -46,62 +45,31 @@
*/
@NotThreadSafe
public final class RetryState {
- public static final int RETRIES = 1;
- public static final int INFINITE_ATTEMPTS = Integer.MAX_VALUE;
+ public static final int MAX_RETRIES = 1;
+ private static final int INFINITE_RETRIES = Integer.MAX_VALUE;
private final LoopState loopState;
private final int attempts;
- private final boolean retryUntilTimeoutThrowsException;
@Nullable
private Throwable previouslyChosenException;
/**
- * Creates a {@code RetryState} with a positive number of allowed retry attempts.
- * {@link Integer#MAX_VALUE} is a special value interpreted as being unlimited.
- *
- * If a timeout is not specified in the {@link TimeoutContext#hasTimeoutMS()}, the specified {@code retries} argument acts as a fallback
- * bound. Otherwise, retries are unbounded until the timeout is reached.
- *
- * It is possible to provide an additional {@code retryPredicate} in the {@link #doAdvanceOrThrow} method,
- * which can be used to stop retrying based on a custom condition additionally to {@code retries} and {@link TimeoutContext}.
- *
- *
- * @param retries A positive number of allowed retry attempts.
- * {@link Integer#MAX_VALUE} is a special value interpreted as being unlimited.
- * @param retryUntilTimeoutThrowsException If {@code true}, then if a {@link MongoOperationTimeoutException} is thrown then retrying stops.
- */
- public static RetryState withRetryableState(final int retries, final boolean retryUntilTimeoutThrowsException) {
- assertTrue(retries > 0);
- return new RetryState(retries, retryUntilTimeoutThrowsException);
- }
-
- public static RetryState withNonRetryableState() {
- return new RetryState(0, false);
- }
-
- /**
- * Creates a {@link RetryState} that does not limit the number of attempts.
- * The number of attempts is limited iff {@link TimeoutContext#hasTimeoutMS()} is true and timeout has expired.
- *
- * It is possible to provide an additional {@code retryPredicate} in the {@link #doAdvanceOrThrow} method,
- * which can be used to stop retrying based on a custom condition additionally to {@link TimeoutContext}.
- *
- *
- * @param timeoutContext A timeout context that will be used to determine if the operation has timed out.
+ * Creates a {@link RetryState} that does not explicitly limit the number of attempts.
+ * Retrying still may be stopped because, for example,
+ * the failed result from the most recent attempt is {@link MongoOperationTimeoutException}.
*/
- public RetryState(final TimeoutContext timeoutContext) {
- this(INFINITE_ATTEMPTS, timeoutContext.hasTimeoutMS());
+ public RetryState() {
+ this(INFINITE_RETRIES);
}
/**
* @param retries A non-negative number of allowed retry attempts.
- * {@link Integer#MAX_VALUE} is a special value interpreted as being unlimited.
+ * {@value #INFINITE_RETRIES} is interpreted as {@linkplain #RetryState() absence of explicit limit}.
*/
- private RetryState(final int retries, final boolean retryUntilTimeoutThrowsException) {
+ public RetryState(final int retries) {
assertTrue(retries >= 0);
loopState = new LoopState();
- attempts = retries == INFINITE_ATTEMPTS ? INFINITE_ATTEMPTS : retries + 1;
- this.retryUntilTimeoutThrowsException = retryUntilTimeoutThrowsException;
+ attempts = retries == INFINITE_RETRIES ? INFINITE_RETRIES : retries + 1;
}
/**
@@ -351,14 +319,14 @@ public boolean isFirstAttempt() {
* An attempt is known to be the last one iff any of the following applies:
*
* - {@link #breakAndThrowIfRetryAnd(Supplier)} / {@link #breakAndCompleteIfRetryAnd(Supplier, SingleResultCallback)} / {@link #markAsLastAttempt()} was called.
- * - A timeout is set and has been reached, as indicated by {@code attemptException}.
- * - No timeout is set, and the number of attempts is limited, and the current attempt is the last one.
+ * - {@code attemptException} is a {@link MongoOperationTimeoutException}.
+ * - The number of attempts is limited, and the current attempt is the last one.
*
*
* @see #attempt()
*/
private boolean isLastAttempt(final Throwable attemptException) {
- boolean operationTimeout = retryUntilTimeoutThrowsException && attemptException instanceof MongoOperationTimeoutException;
+ boolean operationTimeout = attemptException instanceof MongoOperationTimeoutException;
boolean attemptLimit = attempt() == attempts - 1;
return loopState.isLastIteration() || operationTimeout || attemptLimit;
}
@@ -403,7 +371,7 @@ public Optional attachment(final AttachmentKey key) {
public String toString() {
return "RetryState{"
+ "loopState=" + loopState
- + ", attempts=" + (attempts == INFINITE_ATTEMPTS ? "infinite" : attempts)
+ + ", attempts=" + (attempts == INFINITE_RETRIES ? "infinite" : attempts)
+ ", exception=" + previouslyChosenException
+ '}';
}
diff --git a/driver-core/src/main/com/mongodb/internal/async/function/RetryingAsyncCallbackSupplier.java b/driver-core/src/main/com/mongodb/internal/async/function/RetryingAsyncCallbackSupplier.java
index 6ce08513aa..8d12e82e19 100644
--- a/driver-core/src/main/com/mongodb/internal/async/function/RetryingAsyncCallbackSupplier.java
+++ b/driver-core/src/main/com/mongodb/internal/async/function/RetryingAsyncCallbackSupplier.java
@@ -87,13 +87,6 @@ public RetryingAsyncCallbackSupplier(
this.asyncFunction = asyncFunction;
}
- public RetryingAsyncCallbackSupplier(
- final RetryState state,
- final BiPredicate retryPredicate,
- final AsyncCallbackSupplier asyncFunction) {
- this(state, (previouslyChosenFailure, lastAttemptFailure) -> lastAttemptFailure, retryPredicate, asyncFunction);
- }
-
@Override
public void get(final SingleResultCallback callback) {
/* `asyncFunction` and `callback` are the only externally provided pieces of code for which we do not need to care about
diff --git a/driver-core/src/main/com/mongodb/internal/connection/OidcAuthenticator.java b/driver-core/src/main/com/mongodb/internal/connection/OidcAuthenticator.java
index f8c7f3ea89..e002ed3397 100644
--- a/driver-core/src/main/com/mongodb/internal/connection/OidcAuthenticator.java
+++ b/driver-core/src/main/com/mongodb/internal/connection/OidcAuthenticator.java
@@ -335,7 +335,6 @@ private void authenticationLoopAsync(final InternalConnection connection, final
final SingleResultCallback callback) {
fallbackState = FallbackState.INITIAL;
beginAsync().thenRunRetryingWhile(
- operationContext.getTimeoutContext(),
c -> super.authenticateAsync(connection, description, operationContext, c),
e -> triggersRetry(e) && shouldRetryHandler()
).finish(callback);
diff --git a/driver-core/src/main/com/mongodb/internal/operation/CommandOperationHelper.java b/driver-core/src/main/com/mongodb/internal/operation/CommandOperationHelper.java
index 9495adc892..b39cddd654 100644
--- a/driver-core/src/main/com/mongodb/internal/operation/CommandOperationHelper.java
+++ b/driver-core/src/main/com/mongodb/internal/operation/CommandOperationHelper.java
@@ -45,7 +45,7 @@
import static com.mongodb.assertions.Assertions.assertFalse;
import static com.mongodb.assertions.Assertions.assertNotNull;
-import static com.mongodb.internal.async.function.RetryState.INFINITE_ATTEMPTS;
+import static com.mongodb.internal.async.function.RetryState.MAX_RETRIES;
import static com.mongodb.internal.operation.OperationHelper.LOGGER;
import static java.lang.String.format;
import static java.util.Arrays.asList;
@@ -123,11 +123,9 @@ private static Throwable chooseRetryableWriteException(
static RetryState initialRetryState(final boolean retry, final TimeoutContext timeoutContext) {
if (retry) {
- boolean retryUntilTimeoutThrowsException = timeoutContext.hasTimeoutMS();
- int retries = retryUntilTimeoutThrowsException ? INFINITE_ATTEMPTS : RetryState.RETRIES;
- return RetryState.withRetryableState(retries, retryUntilTimeoutThrowsException);
+ return timeoutContext.hasTimeoutMS() ? new RetryState() : new RetryState(MAX_RETRIES);
}
- return RetryState.withNonRetryableState();
+ return new RetryState(0);
}
private static final List RETRYABLE_ERROR_CODES = asList(6, 7, 89, 91, 134, 189, 262, 9001, 13436, 13435, 11602, 11600, 10107);
diff --git a/driver-core/src/main/com/mongodb/internal/operation/MixedBulkWriteOperation.java b/driver-core/src/main/com/mongodb/internal/operation/MixedBulkWriteOperation.java
index 5f916d9d90..53b0f23208 100644
--- a/driver-core/src/main/com/mongodb/internal/operation/MixedBulkWriteOperation.java
+++ b/driver-core/src/main/com/mongodb/internal/operation/MixedBulkWriteOperation.java
@@ -187,7 +187,6 @@ public String getCommandName() {
@Override
public BulkWriteResult execute(final WriteBinding binding, final OperationContext operationContext) {
- TimeoutContext timeoutContext = operationContext.getTimeoutContext();
/* We cannot use the tracking of attempts built in the `RetryState` class because conceptually we have to maintain multiple attempt
* counters while executing a single bulk write operation:
* - a counter that limits attempts to select server and checkout a connection before we created a batch;
@@ -195,8 +194,8 @@ public BulkWriteResult execute(final WriteBinding binding, final OperationContex
* Fortunately, these counters do not exist concurrently with each other. While maintaining the counters manually,
* we must adhere to the contract of `RetryingSyncSupplier`. When the retry timeout is implemented, there will be no counters,
* and the code related to the attempt tracking in `BulkWriteTracker` will be removed. */
- RetryState retryState = new RetryState(timeoutContext);
- BulkWriteTracker.attachNew(retryState, retryWrites, timeoutContext);
+ RetryState retryState = new RetryState();
+ BulkWriteTracker.attachNew(retryState, retryWrites, operationContext.getTimeoutContext());
Supplier retryingBulkWrite = decorateWriteWithRetries(retryState, operationContext, () ->
withSourceAndConnection(binding::getWriteConnectionSource, true, (source, connection, operationContextWithMinRTT) -> {
TimeoutContext timeoutContextWithMinRtt = operationContextWithMinRTT.getTimeoutContext();
@@ -226,10 +225,9 @@ public BulkWriteResult execute(final WriteBinding binding, final OperationContex
}
public void executeAsync(final AsyncWriteBinding binding, final OperationContext operationContext, final SingleResultCallback callback) {
- TimeoutContext timeoutContext = operationContext.getTimeoutContext();
// see the comment in `execute(WriteBinding)` explaining the manual tracking of attempts
- RetryState retryState = new RetryState(timeoutContext);
- BulkWriteTracker.attachNew(retryState, retryWrites, timeoutContext);
+ RetryState retryState = new RetryState();
+ BulkWriteTracker.attachNew(retryState, retryWrites, operationContext.getTimeoutContext());
binding.retain();
AsyncCallbackSupplier retryingBulkWrite = this.decorateWriteWithRetries(retryState,
operationContext,
@@ -493,7 +491,7 @@ private static void attach(final RetryState retryState, final BulkWriteTracker t
private BulkWriteTracker(final boolean retry, @Nullable final BulkWriteBatch batch, final TimeoutContext timeoutContext) {
attempt = 0;
- attempts = retry ? RetryState.RETRIES + 1 : 1;
+ attempts = retry ? RetryState.MAX_RETRIES + 1 : 1;
this.batch = batch;
this.retryUntilTimeoutThrowsException = timeoutContext.hasTimeoutMS();
}
diff --git a/driver-core/src/test/unit/com/mongodb/internal/async/AsyncFunctionsAbstractTest.java b/driver-core/src/test/unit/com/mongodb/internal/async/AsyncFunctionsAbstractTest.java
index 8f6bc7046a..9ce94fc413 100644
--- a/driver-core/src/test/unit/com/mongodb/internal/async/AsyncFunctionsAbstractTest.java
+++ b/driver-core/src/test/unit/com/mongodb/internal/async/AsyncFunctionsAbstractTest.java
@@ -16,8 +16,6 @@
package com.mongodb.internal.async;
import com.mongodb.MongoException;
-import com.mongodb.internal.TimeoutContext;
-import com.mongodb.internal.TimeoutSettings;
import org.junit.jupiter.api.Test;
import java.util.function.BiConsumer;
@@ -29,8 +27,6 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
abstract class AsyncFunctionsAbstractTest extends AsyncFunctionsTestBase {
- private static final TimeoutContext TIMEOUT_CONTEXT = new TimeoutContext(new TimeoutSettings(0, 0, 0, 0L, 0));
-
@Test
void test1Method() {
// the number of expected variations is often: 1 + N methods invoked
@@ -856,7 +852,6 @@ void testRetryLoop() {
},
(callback) -> {
beginAsync().thenRunRetryingWhile(
- TIMEOUT_CONTEXT,
c -> async(plainTest(0) ? 1 : 2, c),
e -> e.getMessage().equals("exception-1")
).finish(callback);
diff --git a/driver-core/src/test/unit/com/mongodb/internal/async/function/RetryStateTest.java b/driver-core/src/test/unit/com/mongodb/internal/async/function/RetryStateTest.java
index 6220753f13..9d6fc2f586 100644
--- a/driver-core/src/test/unit/com/mongodb/internal/async/function/RetryStateTest.java
+++ b/driver-core/src/test/unit/com/mongodb/internal/async/function/RetryStateTest.java
@@ -18,7 +18,6 @@
import com.mongodb.MongoOperationTimeoutException;
import com.mongodb.client.syncadapter.SupplyingCallback;
import com.mongodb.internal.TimeoutContext;
-import com.mongodb.internal.TimeoutSettings;
import com.mongodb.internal.async.function.LoopState.AttachmentKey;
import com.mongodb.internal.operation.retry.AttachmentKeys;
import org.junit.jupiter.api.Assertions;
@@ -44,42 +43,25 @@
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Named.named;
import static org.junit.jupiter.params.provider.Arguments.arguments;
-import static org.mockito.Mockito.mock;
final class RetryStateTest {
- private static final TimeoutContext TIMEOUT_CONTEXT_NO_GLOBAL_TIMEOUT = new TimeoutContext(new TimeoutSettings(0L, 0L,
- 0L, null, 0L));
-
- private static final TimeoutContext TIMEOUT_CONTEXT_EXPIRED_GLOBAL_TIMEOUT = new TimeoutContext(new TimeoutSettings(0L, 0L,
- 0L, 1L, 0L));
-
- private static final TimeoutContext TIMEOUT_CONTEXT_INFINITE_GLOBAL_TIMEOUT = new TimeoutContext(new TimeoutSettings(0L, 0L,
- 0L, 0L, 0L));
private static final String EXPECTED_TIMEOUT_MESSAGE = "Retry attempt exceeded the timeout limit.";
- static Stream infiniteTimeout() {
+ private static Stream atMostTwoRetriesAndUnlimitedRetries() {
return Stream.of(
- arguments(named("Infinite timeoutMs", TIMEOUT_CONTEXT_INFINITE_GLOBAL_TIMEOUT))
- );
+ arguments(named("at most two retries", new RetryState(2))),
+ arguments(named("unlimited retries", new RetryState())));
}
- static Stream expiredTimeout() {
+ private static Stream noRetries() {
return Stream.of(
- arguments(named("Expired timeoutMs", TIMEOUT_CONTEXT_EXPIRED_GLOBAL_TIMEOUT))
- );
+ arguments(named("no retries", new RetryState(0))));
}
- static Stream noTimeout() {
- return Stream.of(
- arguments(named("No timeoutMs", TIMEOUT_CONTEXT_NO_GLOBAL_TIMEOUT))
- );
- }
-
- @ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void unlimitedAttemptsAndAdvance(final TimeoutContext timeoutContext) {
+ @Test
+ void unlimitedAttemptsAndAdvance() {
+ final RetryState retryState = new RetryState();
RuntimeException attemptException = new RuntimeException();
- RetryState retryState = new RetryState(timeoutContext);
assertAll(
() -> assertTrue(retryState.isFirstAttempt()),
() -> assertEquals(0, retryState.attempt())
@@ -99,7 +81,7 @@ void unlimitedAttemptsAndAdvance(final TimeoutContext timeoutContext) {
@Test
void limitedAttemptsAndAdvance() {
- RetryState retryState = RetryState.withNonRetryableState();
+ RetryState retryState = new RetryState(0);
RuntimeException attemptException = new RuntimeException();
assertAll(
() -> assertTrue(retryState.isFirstAttempt()),
@@ -112,54 +94,39 @@ void limitedAttemptsAndAdvance() {
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void markAsLastAttemptAdvanceWithRuntimeException(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void markAsLastAttemptAdvanceWithRuntimeException(final RetryState retryState) {
retryState.markAsLastAttempt();
RuntimeException attemptException = new RuntimeException();
assertAdvanceOrThrowThrows(attemptException, retryState, attemptException, (rs, e) -> fail());
}
@ParameterizedTest(name = "should advance with non-retryable error when marked as last attempt and : ''{0}''")
- @MethodSource({"infiniteTimeout", "expiredTimeout", "noTimeout"})
- void markAsLastAttemptAdvanceWithError(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"noRetries", "atMostTwoRetriesAndUnlimitedRetries"})
+ void markAsLastAttemptAdvanceWithError(final RetryState retryState) {
retryState.markAsLastAttempt();
Error attemptException = new Error();
assertAdvanceOrThrowThrows(attemptException, retryState, attemptException, (rs, e) -> fail());
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void breakAndThrowIfRetryAndFirstAttempt(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void breakAndThrowIfRetryAndFirstAttempt(final RetryState retryState) {
retryState.breakAndThrowIfRetryAnd(Assertions::fail);
assertAdvanceOrThrowDoesNotThrow(retryState, new RuntimeException());
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void breakAndThrowIfRetryAndFalse(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void breakAndThrowIfRetryAndFalse(final RetryState retryState) {
advance(retryState);
retryState.breakAndThrowIfRetryAnd(() -> false);
assertAdvanceOrThrowDoesNotThrow(retryState, new RuntimeException());
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void breakAndThrowIfRetryAndTrue(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
- advance(retryState);
- assertThrows(RuntimeException.class, () -> retryState.breakAndThrowIfRetryAnd(() -> true));
- RuntimeException attemptException = new RuntimeException();
- assertAdvanceOrThrowThrows(attemptException, retryState, attemptException);
- }
-
- @Test
- void breakAndThrowIfRetryAndTrueWithExpiredTimeout() {
- TimeoutContext tContextMock = mock(TimeoutContext.class);
- RetryState retryState = new RetryState(tContextMock);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void breakAndThrowIfRetryAndTrue(final RetryState retryState) {
advance(retryState);
assertThrows(RuntimeException.class, () -> retryState.breakAndThrowIfRetryAnd(() -> true));
RuntimeException attemptException = new RuntimeException();
@@ -167,9 +134,8 @@ void breakAndThrowIfRetryAndTrueWithExpiredTimeout() {
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void breakAndThrowIfRetryIfPredicateThrows(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void breakAndThrowIfRetryIfPredicateThrows(final RetryState retryState) {
advance(retryState);
RuntimeException exception = new RuntimeException();
assertSame(
@@ -181,9 +147,8 @@ void breakAndThrowIfRetryIfPredicateThrows(final TimeoutContext timeoutContext)
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void breakAndCompleteIfRetryAndFirstAttempt(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void breakAndCompleteIfRetryAndFirstAttempt(final RetryState retryState) {
SupplyingCallback> callback = new SupplyingCallback<>();
assertFalse(retryState.breakAndCompleteIfRetryAnd(Assertions::fail, callback));
assertFalse(callback.completed());
@@ -191,9 +156,8 @@ void breakAndCompleteIfRetryAndFirstAttempt(final TimeoutContext timeoutContext)
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void breakAndCompleteIfRetryAndFalse(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void breakAndCompleteIfRetryAndFalse(final RetryState retryState) {
advance(retryState);
SupplyingCallback> callback = new SupplyingCallback<>();
assertFalse(retryState.breakAndCompleteIfRetryAnd(() -> false, callback));
@@ -202,9 +166,8 @@ void breakAndCompleteIfRetryAndFalse(final TimeoutContext timeoutContext) {
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void breakAndCompleteIfRetryAndTrue(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void breakAndCompleteIfRetryAndTrue(final RetryState retryState) {
advance(retryState);
SupplyingCallback> callback = new SupplyingCallback<>();
assertTrue(retryState.breakAndCompleteIfRetryAnd(() -> true, callback));
@@ -214,9 +177,8 @@ void breakAndCompleteIfRetryAndTrue(final TimeoutContext timeoutContext) {
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void breakAndCompleteIfRetryAndPredicateThrows(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void breakAndCompleteIfRetryAndPredicateThrows(final RetryState retryState) {
advance(retryState);
Error exception = new Error();
SupplyingCallback> callback = new SupplyingCallback<>();
@@ -230,19 +192,16 @@ void breakAndCompleteIfRetryAndPredicateThrows(final TimeoutContext timeoutConte
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void advanceOrThrowPredicateFalse(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void advanceOrThrowPredicateFalse(final RetryState retryState) {
RuntimeException attemptException = new RuntimeException();
assertAdvanceOrThrowThrows(attemptException, retryState, attemptException, (rs, e) -> false);
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout"})
- @DisplayName("should rethrow detected timeout exception even if timeout in retry state is not expired")
- void advanceReThrowDetectedTimeoutExceptionEvenIfTimeoutInRetryStateIsNotExpired(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
-
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ @DisplayName("should rethrow detected timeout exception")
+ void advanceReThrowDetectedTimeoutException(final RetryState retryState) {
MongoOperationTimeoutException expectedTimeoutException = TimeoutContext.createMongoTimeoutException("Server selection failed");
assertAdvanceOrThrowThrows(expectedTimeoutException, retryState, expectedTimeoutException,
(e1, e2) -> expectedTimeoutException,
@@ -252,7 +211,7 @@ void advanceReThrowDetectedTimeoutExceptionEvenIfTimeoutInRetryStateIsNotExpired
@Test
@DisplayName("should throw timeout exception from retry, when transformer swallows original timeout exception")
void advanceThrowTimeoutExceptionWhenTransformerSwallowOriginalTimeoutException() {
- RetryState retryState = new RetryState(TIMEOUT_CONTEXT_INFINITE_GLOBAL_TIMEOUT);
+ RetryState retryState = new RetryState();
RuntimeException previousAttemptException = new RuntimeException();
MongoOperationTimeoutException latestAttemptException = TimeoutContext.createMongoTimeoutException("Server selection failed");
@@ -275,7 +234,7 @@ void advanceThrowTimeoutExceptionWhenTransformerSwallowOriginalTimeoutException(
@Test
@DisplayName("should throw original timeout exception from retry, when transformer returns original timeout exception")
void advanceThrowOriginalTimeoutExceptionWhenTransformerReturnsOriginalTimeoutException() {
- RetryState retryState = new RetryState(TIMEOUT_CONTEXT_INFINITE_GLOBAL_TIMEOUT);
+ RetryState retryState = new RetryState();
RuntimeException previousAttemptException = new RuntimeException();
MongoOperationTimeoutException expectedTimeoutException = TimeoutContext
.createMongoTimeoutException("Server selection failed");
@@ -291,15 +250,14 @@ void advanceThrowOriginalTimeoutExceptionWhenTransformerReturnsOriginalTimeoutEx
@Test
void advanceOrThrowPredicateTrueAndLastAttempt() {
- RetryState retryState = RetryState.withNonRetryableState();
+ RetryState retryState = new RetryState(0);
Error attemptException = new Error();
assertAdvanceOrThrowThrows(attemptException, retryState, attemptException);
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void advanceOrThrowPredicateThrowsAfterFirstAttempt(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void advanceOrThrowPredicateThrowsAfterFirstAttempt(final RetryState retryState) {
RuntimeException predicateException = new RuntimeException();
RuntimeException attemptException = new RuntimeException();
assertAdvanceOrThrowThrows(predicateException, retryState, attemptException,
@@ -313,7 +271,7 @@ void advanceOrThrowPredicateThrowsAfterFirstAttempt(final TimeoutContext timeout
@Test
void advanceOrThrowPredicateThrowsTimeoutAfterFirstAttempt() {
- RetryState retryState = new RetryState(TIMEOUT_CONTEXT_EXPIRED_GLOBAL_TIMEOUT);
+ RetryState retryState = new RetryState();
RuntimeException predicateException = new RuntimeException();
RuntimeException attemptException = new MongoOperationTimeoutException(EXPECTED_TIMEOUT_MESSAGE);
MongoOperationTimeoutException mongoOperationTimeoutException = assertThrows(MongoOperationTimeoutException.class,
@@ -328,9 +286,8 @@ void advanceOrThrowPredicateThrowsTimeoutAfterFirstAttempt() {
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void advanceOrThrowPredicateThrows(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void advanceOrThrowPredicateThrows(final RetryState retryState) {
RuntimeException firstAttemptException = new RuntimeException();
retryState.advanceOrThrow(firstAttemptException, (e1, e2) -> e2, (rs, e) -> true);
RuntimeException secondAttemptException = new RuntimeException();
@@ -345,9 +302,8 @@ void advanceOrThrowPredicateThrows(final TimeoutContext timeoutContext) {
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout", "expiredTimeout"})
- void advanceOrThrowTransformerThrowsAfterFirstAttempt(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"noRetries", "atMostTwoRetriesAndUnlimitedRetries"})
+ void advanceOrThrowTransformerThrowsAfterFirstAttempt(final RetryState retryState) {
RuntimeException transformerException = new RuntimeException();
assertAdvanceOrThrowThrows(transformerException, retryState, new AssertionError(),
(e1, e2) -> {
@@ -357,9 +313,8 @@ void advanceOrThrowTransformerThrowsAfterFirstAttempt(final TimeoutContext timeo
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void advanceOrThrowTransformerThrows(final TimeoutContext timeoutContext) throws Throwable {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void advanceOrThrowTransformerThrows(final RetryState retryState) throws Throwable {
Error firstAttemptException = new Error();
retryState.advanceOrThrow(firstAttemptException, (e1, e2) -> e2, (rs, e) -> true);
RuntimeException transformerException = new RuntimeException();
@@ -371,9 +326,8 @@ void advanceOrThrowTransformerThrows(final TimeoutContext timeoutContext) throws
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void advanceOrThrowTransformAfterFirstAttempt(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void advanceOrThrowTransformAfterFirstAttempt(final RetryState retryState) {
RuntimeException attemptException = new RuntimeException();
RuntimeException transformerResult = new RuntimeException();
assertAdvanceOrThrowThrows(transformerResult, retryState, attemptException,
@@ -390,7 +344,7 @@ void advanceOrThrowTransformAfterFirstAttempt(final TimeoutContext timeoutContex
@Test
void advanceOrThrowTransformThrowsTimeoutExceptionAfterFirstAttempt() {
- RetryState retryState = new RetryState(TIMEOUT_CONTEXT_EXPIRED_GLOBAL_TIMEOUT);
+ RetryState retryState = new RetryState();
RuntimeException attemptException = new MongoOperationTimeoutException(EXPECTED_TIMEOUT_MESSAGE);
RuntimeException transformerResult = new RuntimeException();
@@ -412,9 +366,8 @@ void advanceOrThrowTransformThrowsTimeoutExceptionAfterFirstAttempt() {
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void advanceOrThrowTransform(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void advanceOrThrowTransform(final RetryState retryState) {
RuntimeException firstAttemptException = new RuntimeException();
retryState.advanceOrThrow(firstAttemptException, (e1, e2) -> e2, (rs, e) -> true);
RuntimeException secondAttemptException = new RuntimeException();
@@ -432,9 +385,8 @@ void advanceOrThrowTransform(final TimeoutContext timeoutContext) {
}
@ParameterizedTest
- @MethodSource({"infiniteTimeout", "noTimeout"})
- void attachAndAttachment(final TimeoutContext timeoutContext) {
- RetryState retryState = new RetryState(timeoutContext);
+ @MethodSource({"atMostTwoRetriesAndUnlimitedRetries"})
+ void attachAndAttachment(final RetryState retryState) {
AttachmentKey attachmentKey = AttachmentKeys.maxWireVersion();
int attachmentValue = 1;
assertFalse(retryState.attachment(attachmentKey).isPresent());