@@ -106,10 +106,17 @@ public class OkHttpServices implements RESTServices {
106106 * in several places and is slightly different in each place. It's also not possible to implement this logic in an
107107 * OkHttp interceptor as the logic needs access to details that are not available to an interceptor.
108108 */
109- private final Random randRetry = new Random ();
110- private int maxDelay = DEFAULT_MAX_DELAY ;
111- private int minRetry = DEFAULT_MIN_RETRY ;
112- private final Set <Integer > retryStatus = new HashSet <>();
109+ private final Random randomForRetryDelay = new Random ();
110+
111+ // The maximum amount of time to spend retrying requests.
112+ private int maxDelayForRetries = DEFAULT_MAX_DELAY ;
113+
114+ // The minimum number of retry attempts to make regardless of the max delay.
115+ private int minRetryAttempts = DEFAULT_MIN_RETRY ;
116+
117+ // The HTTP status codes that are retryable.
118+ private static final Set <Integer > RETRYABLE_STATUS_CODES =
119+ Set .of (STATUS_BAD_GATEWAY , STATUS_SERVICE_UNAVAILABLE , STATUS_GATEWAY_TIMEOUT );
113120
114121 private boolean checkFirstRequest = true ;
115122
@@ -129,10 +136,6 @@ public record ConnectionConfig(String host, int port, String basePath, String da
129136 }
130137
131138 public OkHttpServices (ConnectionConfig connectionConfig ) {
132- retryStatus .add (STATUS_BAD_GATEWAY );
133- retryStatus .add (STATUS_SERVICE_UNAVAILABLE );
134- retryStatus .add (STATUS_GATEWAY_TIMEOUT );
135-
136139 this .okHttpClient = connect (connectionConfig );
137140 }
138141
@@ -239,13 +242,13 @@ private void configureDelayAndRetry(Properties props) {
239242 if (props .containsKey (MAX_DELAY_PROP )) {
240243 int max = Utilities .parseInt (props .getProperty (MAX_DELAY_PROP ));
241244 if (max > 0 ) {
242- maxDelay = max * 1000 ;
245+ maxDelayForRetries = max * 1000 ;
243246 }
244247 }
245248 if (props .containsKey (MIN_RETRY_PROP )) {
246249 int min = Utilities .parseInt (props .getProperty (MIN_RETRY_PROP ));
247250 if (min > 0 ) {
248- minRetry = min ;
251+ minRetryAttempts = min ;
249252 }
250253 }
251254 }
@@ -289,7 +292,7 @@ private int makeFirstRequest(int retry) {
289292 private int makeFirstRequest (HttpUrl requestUri , String path , int retry ) {
290293 Response response = sendRequestOnce (setupRequest (requestUri , path , null ).head ());
291294 int statusCode = response .code ();
292- if (!retryStatus .contains (statusCode )) {
295+ if (!RETRYABLE_STATUS_CODES .contains (statusCode )) {
293296 closeResponse (response );
294297 return 0 ;
295298 }
@@ -298,7 +301,7 @@ private int makeFirstRequest(HttpUrl requestUri, String path, int retry) {
298301 closeResponse (response );
299302
300303 int retryAfter = Utilities .parseInt (retryAfterRaw );
301- return Math .max (retryAfter , calculateDelay (randRetry , retry ));
304+ return Math .max (retryAfter , calculateDelay (retry ));
302305 }
303306
304307 private RequestParameters addTemporalProtectionParams (RequestParameters params , String uri , ProtectionLevel level ,
@@ -518,7 +521,7 @@ private Response sendRequestWithRetry(
518521 /*
519522 * This loop is for retrying the request if the service is unavailable
520523 */
521- for (; retry < minRetry || (System .currentTimeMillis () - startTime ) < maxDelay ; retry ++) {
524+ for (; retry < minRetryAttempts || (System .currentTimeMillis () - startTime ) < maxDelayForRetries ; retry ++) {
522525 if (nextDelay > 0 ) {
523526 try {
524527 Thread .sleep (nextDelay );
@@ -537,7 +540,7 @@ private Response sendRequestWithRetry(
537540 );
538541 }
539542 status = response .code ();
540- if (!isRetryable || !retryStatus .contains (status )) {
543+ if (!isRetryable || !RETRYABLE_STATUS_CODES .contains (status )) {
541544 if (isFirstRequest ()) setFirstRequest (false );
542545 /*
543546 * If we don't get a service unavailable status or if the request
@@ -562,13 +565,13 @@ private Response sendRequestWithRetry(
562565 /*
563566 * Calculate the delay before which we shouldn't retry
564567 */
565- nextDelay = Math .max (getRetryAfterTime (response ), calculateDelay (randRetry , retry ));
568+ nextDelay = Math .max (getRetryAfterTime (response ), calculateDelay (retry ));
566569 }
567570 /*
568571 * If the service is still unavailable after all the retries, we throw a
569572 * FailedRetryException indicating that the service is unavailable.
570573 */
571- if (retryStatus .contains (status )) {
574+ if (RETRYABLE_STATUS_CODES .contains (status )) {
572575 checkFirstRequest ();
573576 closeResponse (response );
574577 throw new FailedRetryException (
@@ -1198,7 +1201,7 @@ private TemporalDescriptor putPostDocumentImpl(RequestLogger reqlog, String meth
11981201 long startTime = System .currentTimeMillis ();
11991202 int nextDelay = 0 ;
12001203 int retry = 0 ;
1201- for (; retry < minRetry || (System .currentTimeMillis () - startTime ) < maxDelay ; retry ++) {
1204+ for (; retry < minRetryAttempts || (System .currentTimeMillis () - startTime ) < maxDelayForRetries ; retry ++) {
12021205 if (nextDelay > 0 ) {
12031206 try {
12041207 Thread .sleep (nextDelay );
@@ -1238,7 +1241,7 @@ private TemporalDescriptor putPostDocumentImpl(RequestLogger reqlog, String meth
12381241 status = response .code ();
12391242
12401243 responseHeaders = response .headers ();
1241- if (transaction != null || !retryStatus .contains (status )) {
1244+ if (transaction != null || !RETRYABLE_STATUS_CODES .contains (status )) {
12421245 if (isFirstRequest ()) setFirstRequest (false );
12431246
12441247 break ;
@@ -1255,9 +1258,9 @@ private TemporalDescriptor putPostDocumentImpl(RequestLogger reqlog, String meth
12551258 }
12561259
12571260 int retryAfter = Utilities .parseInt (retryAfterRaw );
1258- nextDelay = Math .max (retryAfter , calculateDelay (randRetry , retry ));
1261+ nextDelay = Math .max (retryAfter , calculateDelay (retry ));
12591262 }
1260- if (retryStatus .contains (status )) {
1263+ if (RETRYABLE_STATUS_CODES .contains (status )) {
12611264 checkFirstRequest ();
12621265 closeResponse (response );
12631266 throw new FailedRetryException (
@@ -1359,7 +1362,7 @@ private TemporalDescriptor putPostDocumentImpl(RequestLogger reqlog, String meth
13591362 long startTime = System .currentTimeMillis ();
13601363 int nextDelay = 0 ;
13611364 int retry = 0 ;
1362- for (; retry < minRetry || (System .currentTimeMillis () - startTime ) < maxDelay ; retry ++) {
1365+ for (; retry < minRetryAttempts || (System .currentTimeMillis () - startTime ) < maxDelayForRetries ; retry ++) {
13631366 if (nextDelay > 0 ) {
13641367 try {
13651368 Thread .sleep (nextDelay );
@@ -1382,7 +1385,7 @@ private TemporalDescriptor putPostDocumentImpl(RequestLogger reqlog, String meth
13821385 status = response .code ();
13831386
13841387 responseHeaders = response .headers ();
1385- if (transaction != null || !retryStatus .contains (status )) {
1388+ if (transaction != null || !RETRYABLE_STATUS_CODES .contains (status )) {
13861389 if (isFirstRequest ()) setFirstRequest (false );
13871390
13881391 break ;
@@ -1397,9 +1400,9 @@ private TemporalDescriptor putPostDocumentImpl(RequestLogger reqlog, String meth
13971400 }
13981401
13991402 int retryAfter = Utilities .parseInt (retryAfterRaw );
1400- nextDelay = Math .max (retryAfter , calculateDelay (randRetry , retry ));
1403+ nextDelay = Math .max (retryAfter , calculateDelay (retry ));
14011404 }
1402- if (retryStatus .contains (status )) {
1405+ if (RETRYABLE_STATUS_CODES .contains (status )) {
14031406 checkFirstRequest ();
14041407 closeResponse (response );
14051408 throw new FailedRetryException (
@@ -2092,7 +2095,7 @@ Response getResponse() {
20922095 long startTime = System .currentTimeMillis ();
20932096 int nextDelay = 0 ;
20942097 int retry = 0 ;
2095- for (; retry < minRetry || (System .currentTimeMillis () - startTime ) < maxDelay ; retry ++) {
2098+ for (; retry < minRetryAttempts || (System .currentTimeMillis () - startTime ) < maxDelayForRetries ; retry ++) {
20962099 if (nextDelay > 0 ) {
20972100 try {
20982101 Thread .sleep (nextDelay );
@@ -2121,7 +2124,7 @@ Response getResponse() {
21212124
21222125 status = response .code ();
21232126
2124- if (transaction != null || !retryStatus .contains (status )) {
2127+ if (transaction != null || !RETRYABLE_STATUS_CODES .contains (status )) {
21252128 if (isFirstRequest ()) setFirstRequest (false );
21262129
21272130 break ;
@@ -2132,9 +2135,9 @@ Response getResponse() {
21322135
21332136 closeResponse (response );
21342137
2135- nextDelay = Math .max (retryAfter , calculateDelay (randRetry , retry ));
2138+ nextDelay = Math .max (retryAfter , calculateDelay (retry ));
21362139 }
2137- if (retryStatus .contains (status )) {
2140+ if (RETRYABLE_STATUS_CODES .contains (status )) {
21382141 checkFirstRequest ();
21392142 closeResponse (response );
21402143 throw new FailedRetryException (
@@ -2631,7 +2634,7 @@ private void putPostValueImpl(RequestLogger reqlog, String method,
26312634 long startTime = System .currentTimeMillis ();
26322635 int nextDelay = 0 ;
26332636 int retry = 0 ;
2634- for (; retry < minRetry || (System .currentTimeMillis () - startTime ) < maxDelay ; retry ++) {
2637+ for (; retry < minRetryAttempts || (System .currentTimeMillis () - startTime ) < maxDelayForRetries ; retry ++) {
26352638 if (nextDelay > 0 ) {
26362639 try {
26372640 Thread .sleep (nextDelay );
@@ -2693,7 +2696,7 @@ private void putPostValueImpl(RequestLogger reqlog, String method,
26932696
26942697 status = response .code ();
26952698
2696- if (!retryStatus .contains (status )) {
2699+ if (!RETRYABLE_STATUS_CODES .contains (status )) {
26972700 if (isFirstRequest ()) setFirstRequest (false );
26982701 break ;
26992702 }
@@ -2708,9 +2711,9 @@ private void putPostValueImpl(RequestLogger reqlog, String method,
27082711 }
27092712
27102713 int retryAfter = Utilities .parseInt (retryAfterRaw );
2711- nextDelay = Math .max (retryAfter , calculateDelay (randRetry , retry ));
2714+ nextDelay = Math .max (retryAfter , calculateDelay (retry ));
27122715 }
2713- if (retryStatus .contains (status )) {
2716+ if (RETRYABLE_STATUS_CODES .contains (status )) {
27142717 checkFirstRequest ();
27152718 closeResponse (response );
27162719 throw new FailedRetryException (
@@ -3064,7 +3067,7 @@ public <R extends AbstractReadHandle, W extends AbstractWriteHandle> R putResour
30643067 long startTime = System .currentTimeMillis ();
30653068 int nextDelay = 0 ;
30663069 int retry = 0 ;
3067- for (; retry < minRetry || (System .currentTimeMillis () - startTime ) < maxDelay ; retry ++) {
3070+ for (; retry < minRetryAttempts || (System .currentTimeMillis () - startTime ) < maxDelayForRetries ; retry ++) {
30683071 if (nextDelay > 0 ) {
30693072 try {
30703073 Thread .sleep (nextDelay );
@@ -3083,7 +3086,7 @@ public <R extends AbstractReadHandle, W extends AbstractWriteHandle> R putResour
30833086 response = doPut (requestBldr , multiPart , hasStreamingPart );
30843087 status = response .code ();
30853088
3086- if (transaction != null || !retryStatus .contains (status )) {
3089+ if (transaction != null || !RETRYABLE_STATUS_CODES .contains (status )) {
30873090 if (isFirstRequest ()) setFirstRequest (false );
30883091
30893092 break ;
@@ -3098,9 +3101,9 @@ public <R extends AbstractReadHandle, W extends AbstractWriteHandle> R putResour
30983101 }
30993102
31003103 int retryAfter = Utilities .parseInt (retryAfterRaw );
3101- nextDelay = Math .max (retryAfter , calculateDelay (randRetry , retry ));
3104+ nextDelay = Math .max (retryAfter , calculateDelay (retry ));
31023105 }
3103- if (retryStatus .contains (status )) {
3106+ if (RETRYABLE_STATUS_CODES .contains (status )) {
31043107 checkFirstRequest ();
31053108 closeResponse (response );
31063109 throw new FailedRetryException (
@@ -3238,7 +3241,7 @@ public <R extends AbstractReadHandle, W extends AbstractWriteHandle> R postResou
32383241 long startTime = System .currentTimeMillis ();
32393242 int nextDelay = 0 ;
32403243 int retry = 0 ;
3241- for (; retry < minRetry || (System .currentTimeMillis () - startTime ) < maxDelay ; retry ++) {
3244+ for (; retry < minRetryAttempts || (System .currentTimeMillis () - startTime ) < maxDelayForRetries ; retry ++) {
32423245 if (nextDelay > 0 ) {
32433246 try {
32443247 Thread .sleep (nextDelay );
@@ -3257,7 +3260,7 @@ public <R extends AbstractReadHandle, W extends AbstractWriteHandle> R postResou
32573260 response = doPost (requestBldr , multiPart , hasStreamingPart );
32583261 status = response .code ();
32593262
3260- if (transaction != null || !retryStatus .contains (status )) {
3263+ if (transaction != null || !RETRYABLE_STATUS_CODES .contains (status )) {
32613264 if (isFirstRequest ()) setFirstRequest (false );
32623265
32633266 break ;
@@ -3272,9 +3275,9 @@ public <R extends AbstractReadHandle, W extends AbstractWriteHandle> R postResou
32723275 }
32733276
32743277 int retryAfter = Utilities .parseInt (retryAfterRaw );
3275- nextDelay = Math .max (retryAfter , calculateDelay (randRetry , retry ));
3278+ nextDelay = Math .max (retryAfter , calculateDelay (retry ));
32763279 }
3277- if (retryStatus .contains (status )) {
3280+ if (RETRYABLE_STATUS_CODES .contains (status )) {
32783281 checkFirstRequest ();
32793282 closeResponse (response );
32803283 throw new FailedRetryException (
@@ -3848,7 +3851,7 @@ private <W extends AbstractWriteHandle, U extends OkHttpResultIterator> U postIt
38483851 long startTime = System .currentTimeMillis ();
38493852 int nextDelay = 0 ;
38503853 int retry = 0 ;
3851- for (; retry < minRetry || (System .currentTimeMillis () - startTime ) < maxDelay ; retry ++) {
3854+ for (; retry < minRetryAttempts || (System .currentTimeMillis () - startTime ) < maxDelayForRetries ; retry ++) {
38523855 if (nextDelay > 0 ) {
38533856 try {
38543857 Thread .sleep (nextDelay );
@@ -3870,7 +3873,7 @@ private <W extends AbstractWriteHandle, U extends OkHttpResultIterator> U postIt
38703873 response = doPost (requestBldr , multiPart , hasStreamingPart );
38713874 status = response .code ();
38723875
3873- if (transaction != null || !retryStatus .contains (status )) {
3876+ if (transaction != null || !RETRYABLE_STATUS_CODES .contains (status )) {
38743877 if (isFirstRequest ()) setFirstRequest (false );
38753878
38763879 break ;
@@ -3885,9 +3888,9 @@ private <W extends AbstractWriteHandle, U extends OkHttpResultIterator> U postIt
38853888 }
38863889
38873890 int retryAfter = Utilities .parseInt (retryAfterRaw );
3888- nextDelay = Math .max (retryAfter , calculateDelay (randRetry , retry ));
3891+ nextDelay = Math .max (retryAfter , calculateDelay (retry ));
38893892 }
3890- if (retryStatus .contains (status )) {
3893+ if (RETRYABLE_STATUS_CODES .contains (status )) {
38913894 checkFirstRequest ();
38923895 closeResponse (response );
38933896 throw new FailedRetryException (
@@ -4453,17 +4456,17 @@ private String stringJoin(Collection collection, String separator,
44534456 return (builder != null ) ? builder .toString () : null ;
44544457 }
44554458
4456- private int calculateDelay (Random rand , int i ) {
4459+ private int calculateDelay (int attempt ) {
44574460 int min =
4458- (i > 6 ) ? DELAY_CEILING :
4459- (i == 0 ) ? DELAY_FLOOR :
4460- DELAY_FLOOR + (1 << i ) * DELAY_MULTIPLIER ;
4461+ (attempt > 6 ) ? DELAY_CEILING :
4462+ (attempt == 0 ) ? DELAY_FLOOR :
4463+ DELAY_FLOOR + (1 << attempt ) * DELAY_MULTIPLIER ;
44614464 int range =
4462- (i > 6 ) ? DELAY_FLOOR :
4463- (i == 0 ) ? 2 * DELAY_MULTIPLIER :
4464- (i == 6 ) ? DELAY_CEILING - min :
4465- (1 << i ) * DELAY_MULTIPLIER ;
4466- return min + randRetry .nextInt (range );
4465+ (attempt > 6 ) ? DELAY_FLOOR :
4466+ (attempt == 0 ) ? 2 * DELAY_MULTIPLIER :
4467+ (attempt == 6 ) ? DELAY_CEILING - min :
4468+ (1 << attempt ) * DELAY_MULTIPLIER ;
4469+ return min + randomForRetryDelay .nextInt (range );
44674470 }
44684471
44694472 static class OkHttpResult {
@@ -4967,7 +4970,7 @@ public InputStream match(QueryDefinition queryDef,
49674970 long startTime = System .currentTimeMillis ();
49684971 int nextDelay = 0 ;
49694972 int retry = 0 ;
4970- for (; retry < minRetry || (System .currentTimeMillis () - startTime ) < maxDelay ; retry ++) {
4973+ for (; retry < minRetryAttempts || (System .currentTimeMillis () - startTime ) < maxDelayForRetries ; retry ++) {
49714974 if (nextDelay > 0 ) {
49724975 try {
49734976 Thread .sleep (nextDelay );
@@ -4987,7 +4990,7 @@ public InputStream match(QueryDefinition queryDef,
49874990 }
49884991 status = response .code ();
49894992
4990- if (!retryStatus .contains (status )) {
4993+ if (!RETRYABLE_STATUS_CODES .contains (status )) {
49914994 if (isFirstRequest ()) setFirstRequest (false );
49924995
49934996 break ;
@@ -4998,9 +5001,9 @@ public InputStream match(QueryDefinition queryDef,
49985001
49995002 closeResponse (response );
50005003
5001- nextDelay = Math .max (retryAfter , calculateDelay (randRetry , retry ));
5004+ nextDelay = Math .max (retryAfter , calculateDelay (retry ));
50025005 }
5003- if (retryStatus .contains (status )) {
5006+ if (RETRYABLE_STATUS_CODES .contains (status )) {
50045007 checkFirstRequest ();
50055008 closeResponse (response );
50065009 throw new FailedRetryException (
0 commit comments