Skip to content

Commit 4df0f94

Browse files
committed
PR feedback
1 parent 098b4b4 commit 4df0f94

5 files changed

Lines changed: 180 additions & 505 deletions

File tree

driver-core/src/main/com/mongodb/internal/ExponentialBackoff.java

Lines changed: 0 additions & 192 deletions
This file was deleted.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.mongodb.internal.time;
18+
19+
import com.mongodb.annotations.NotThreadSafe;
20+
import com.mongodb.internal.VisibleForTesting;
21+
22+
import java.util.concurrent.ThreadLocalRandom;
23+
import java.util.function.DoubleSupplier;
24+
25+
import static com.mongodb.internal.VisibleForTesting.AccessModifier.PRIVATE;
26+
27+
/**
28+
* Implements exponential backoff with jitter for retry scenarios.
29+
*/
30+
@NotThreadSafe
31+
public enum ExponentialBackoff {
32+
TRANSACTION(5.0, 500.0, 1.5);
33+
34+
private final double baseMs, maxMs, growth;
35+
36+
// TODO remove this global state once https://jira.mongodb.org/browse/JAVA-6060 is done
37+
private static DoubleSupplier testJitterSupplier = null;
38+
39+
ExponentialBackoff(final double baseMs, final double maxMs, final double growth) {
40+
this.baseMs = baseMs;
41+
this.maxMs = maxMs;
42+
this.growth = growth;
43+
}
44+
45+
/**
46+
* Calculate the next delay in milliseconds based on the retry count.
47+
*
48+
* @param retryCount The number of retries that have occurred.
49+
* @return The calculated delay in milliseconds.
50+
*/
51+
public long calculateDelayBeforeNextRetryMs(final int retryCount) {
52+
double jitter = testJitterSupplier != null
53+
? testJitterSupplier.getAsDouble()
54+
: ThreadLocalRandom.current().nextDouble();
55+
double backoff = Math.min(baseMs * Math.pow(growth, retryCount), maxMs);
56+
return Math.round(jitter * backoff);
57+
}
58+
59+
/**
60+
* Calculate the next delay in milliseconds based on the retry count and a provided jitter.
61+
*
62+
* @param retryCount The number of retries that have occurred.
63+
* @param jitter A double in the range [0, 1) to apply as jitter.
64+
* @return The calculated delay in milliseconds.
65+
*/
66+
public long calculateDelayBeforeNextRetryMs(final int retryCount, final double jitter) {
67+
double backoff = Math.min(baseMs * Math.pow(growth, retryCount), maxMs);
68+
return Math.round(jitter * backoff);
69+
}
70+
71+
/**
72+
* Set a custom jitter supplier for testing purposes.
73+
*
74+
* @param supplier A DoubleSupplier that returns values in [0, 1) range.
75+
*/
76+
@VisibleForTesting(otherwise = PRIVATE)
77+
public static void setTestJitterSupplier(final DoubleSupplier supplier) {
78+
testJitterSupplier = supplier;
79+
}
80+
81+
/**
82+
* Clear the test jitter supplier, reverting to default ThreadLocalRandom behavior.
83+
*/
84+
@VisibleForTesting(otherwise = PRIVATE)
85+
public static void clearTestJitterSupplier() {
86+
testJitterSupplier = null;
87+
}
88+
}

0 commit comments

Comments
 (0)