11package com .contentstack .cms .core ;
22
33import org .jetbrains .annotations .NotNull ;
4+
45import retrofit2 .Call ;
56import retrofit2 .Callback ;
7+ import retrofit2 .HttpException ;
68
79import java .util .logging .Logger ;
810
11+ import retrofit2 .Response ;
12+
13+ import java .io .IOException ;
14+ import java .net .SocketTimeoutException ;
15+
916/**
1017 * The Contentstack RetryCallback
1118 *
12- * @author ***REMOVED***
13- * @version v0.1.0
19+ * @author ***REMOVED ** @version v0.1.0
1420 * @since 2022-10-20
1521 */
1622public abstract class RetryCallback <T > implements Callback <T > {
@@ -19,9 +25,9 @@ public abstract class RetryCallback<T> implements Callback<T> {
1925 // variables for the
2026 // `RetryCallback` class:
2127 private final Logger log = Logger .getLogger (RetryCallback .class .getName ());
22- private static final int TOTAL_RETRIES = 3 ;
2328 private final Call <T > call ;
2429 private int retryCount = 0 ;
30+ private final RetryConfig retryConfig ;
2531
2632 // The `protected RetryCallback(Call<T> call)` constructor is used to
2733 // instantiate a new `RetryCallback`
@@ -30,28 +36,48 @@ public abstract class RetryCallback<T> implements Callback<T> {
3036 // The constructor assigns this `Call<T>` object to the `call` instance
3137 // variable.
3238 protected RetryCallback (Call <T > call ) {
39+ this (call , null );
40+ }
41+
42+ protected RetryCallback (Call <T > call , RetryConfig retryConfig ) {
3343 this .call = call ;
44+ this .retryConfig = retryConfig != null ? retryConfig : RetryConfig .defaultConfig ();
3445 }
3546
3647 /**
37- * The function logs the localized message of the thrown exception and retries
38- * the API call if the
39- * retry count is less than the total number of retries allowed.
48+ * The function logs the localized message of the thrown exception and
49+ * retries the API call if the retry count is less than the total number of
50+ * retries allowed.
4051 *
41- * @param call The `Call` object represents the network call that was made. It
42- * contains information
43- * about the request and response.
44- * @param t The parameter `t` is the `Throwable` object that represents the
45- * exception or error that
46- * occurred during the execution of the network call. It contains
47- * information about the error, such as
48- * the error message and stack trace.
52+ * @param call The `Call` object represents the network call that was made.
53+ * It contains information about the request and response.
54+ * @param t The parameter `t` is the `Throwable` object that represents the
55+ * exception or error that occurred during the execution of the network
56+ * call. It contains information about the error, such as the error message
57+ * and stack trace.
4958 */
5059 @ Override
5160 public void onFailure (@ NotNull Call <T > call , Throwable t ) {
52- log .info (t .getLocalizedMessage ());
53- if (retryCount ++ < TOTAL_RETRIES ) {
54- retry ();
61+ int statusCode = extractStatusCode (t );
62+
63+ if (!retryConfig .getRetryCondition ().shouldRetry (statusCode , t )) {
64+ onFinalFailure (call , t );
65+ } else {
66+ if (retryCount >= retryConfig .getRetryLimit ()) {
67+ onFinalFailure (call ,t );
68+ } else {
69+ retryCount ++;
70+ long delay = RetryUtil .calculateDelay (retryConfig , retryCount , statusCode );
71+ try {
72+ Thread .sleep (delay );
73+ } catch (InterruptedException ex ) {
74+ Thread .currentThread ().interrupt ();
75+ log .log (java .util .logging .Level .WARNING , "Retry interrupted" , ex );
76+ onFinalFailure (call , t );
77+ return ;
78+ }
79+ retry ();
80+ }
5581 }
5682 }
5783
@@ -61,4 +87,22 @@ public void onFailure(@NotNull Call<T> call, Throwable t) {
6187 private void retry () {
6288 call .clone ().enqueue (this );
6389 }
90+
91+ private int extractStatusCode (Throwable t ) {
92+ if (t instanceof HttpException ) {
93+ Response <?> response = ((HttpException ) t ).response ();
94+ if (response != null ) {
95+ return response .code ();
96+ } else {
97+ return -1 ;
98+ }
99+ } else if (t instanceof IOException || t instanceof SocketTimeoutException ) {
100+ return 0 ;
101+ }
102+ return -1 ;
103+ }
104+
105+ protected void onFinalFailure (Call <T > call , Throwable t ) {
106+ log .warning ("Final failure after " + retryCount + " retries: " + (t != null ? t .getMessage () : "" ));
107+ }
64108}
0 commit comments