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
1419 * @since 2022-10-20
1520 */
1621public abstract class RetryCallback <T > implements Callback <T > {
@@ -19,9 +24,9 @@ public abstract class RetryCallback<T> implements Callback<T> {
1924 // variables for the
2025 // `RetryCallback` class:
2126 private final Logger log = Logger .getLogger (RetryCallback .class .getName ());
22- private static final int TOTAL_RETRIES = 3 ;
2327 private final Call <T > call ;
2428 private int retryCount = 0 ;
29+ private final RetryConfig retryConfig ;
2530
2631 // The `protected RetryCallback(Call<T> call)` constructor is used to
2732 // instantiate a new `RetryCallback`
@@ -30,28 +35,48 @@ public abstract class RetryCallback<T> implements Callback<T> {
3035 // The constructor assigns this `Call<T>` object to the `call` instance
3136 // variable.
3237 protected RetryCallback (Call <T > call ) {
38+ this (call , null );
39+ }
40+
41+ protected RetryCallback (Call <T > call , RetryConfig retryConfig ) {
3342 this .call = call ;
43+ this .retryConfig = retryConfig != null ? retryConfig : RetryConfig .defaultConfig ();
3444 }
3545
3646 /**
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.
47+ * The function logs the localized message of the thrown exception and
48+ * retries the API call if the retry count is less than the total number of
49+ * retries allowed.
4050 *
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.
51+ * @param call The `Call` object represents the network call that was made.
52+ * It contains information about the request and response.
53+ * @param t The parameter `t` is the `Throwable` object that represents the
54+ * exception or error that occurred during the execution of the network
55+ * call. It contains information about the error, such as the error message
56+ * and stack trace.
4957 */
5058 @ Override
5159 public void onFailure (@ NotNull Call <T > call , Throwable t ) {
52- log .info (t .getLocalizedMessage ());
53- if (retryCount ++ < TOTAL_RETRIES ) {
54- retry ();
60+ int statusCode = extractStatusCode (t );
61+
62+ if (!retryConfig .getRetryCondition ().shouldRetry (statusCode , t )) {
63+ onFinalFailure (call , t );
64+ } else {
65+ if (retryCount >= retryConfig .getRetryLimit ()) {
66+ onFinalFailure (call ,t );
67+ } else {
68+ retryCount ++;
69+ long delay = RetryUtil .calculateDelay (retryConfig , retryCount , statusCode );
70+ try {
71+ Thread .sleep (delay );
72+ } catch (InterruptedException ex ) {
73+ Thread .currentThread ().interrupt ();
74+ log .log (java .util .logging .Level .WARNING , "Retry interrupted" , ex );
75+ onFinalFailure (call , t );
76+ return ;
77+ }
78+ retry ();
79+ }
5580 }
5681 }
5782
@@ -61,4 +86,22 @@ public void onFailure(@NotNull Call<T> call, Throwable t) {
6186 private void retry () {
6287 call .clone ().enqueue (this );
6388 }
89+
90+ private int extractStatusCode (Throwable t ) {
91+ if (t instanceof HttpException ) {
92+ Response <?> response = ((HttpException ) t ).response ();
93+ if (response != null ) {
94+ return response .code ();
95+ } else {
96+ return -1 ;
97+ }
98+ } else if (t instanceof IOException || t instanceof SocketTimeoutException ) {
99+ return 0 ;
100+ }
101+ return -1 ;
102+ }
103+
104+ protected void onFinalFailure (Call <T > call , Throwable t ) {
105+ log .warning ("Final failure after " + retryCount + " retries: " + (t != null ? t .getMessage () : "" ));
106+ }
64107}
0 commit comments