Last active
September 8, 2024 15:40
-
-
Save smarteist/3e0a892a5c294932d108020f46e274f4 to your computer and use it in GitHub Desktop.
its a retry policy interceptor for retrofit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.util.Log; | |
import okhttp3.Interceptor; | |
import okhttp3.Request; | |
import okhttp3.Response; | |
import java.io.IOException; | |
import java.net.SocketTimeoutException; | |
public class RetryPolicyInterceptor implements Interceptor { | |
public enum RetryStrategy { | |
LINEAR, | |
EXPONENTIAL | |
} | |
private final int maxRetries; | |
private final long retryDelayMillis; | |
private final RetryStrategy retryStrategy; | |
public RetryPolicyInterceptor(int maxRetries, long retryDelayMillis, RetryStrategy retryStrategy) { | |
this.maxRetries = maxRetries; | |
this.retryDelayMillis = retryDelayMillis; | |
this.retryStrategy = retryStrategy; | |
} | |
@Override | |
public Response intercept(Chain chain) throws IOException { | |
Request request = chain.request(); | |
Response response = null; | |
IOException lastException = null; | |
int attempt = 0; | |
while (attempt < maxRetries) { | |
try { | |
// Close the previous response to avoid memory leaks | |
if (response != null) { | |
response.close(); | |
} | |
response = chain.proceed(request); | |
// Check if response is successful or not a server error | |
if (response.isSuccessful() || !isServerError(response)) { | |
return response; | |
} | |
} catch (IOException e) { | |
// Retry only if it's a timeout exception | |
if (isTimeoutException(e)) { | |
lastException = e; | |
} else { | |
throw e; // Other IOExceptions are not retried | |
} | |
} | |
attempt++; | |
waitBeforeRetry(attempt); | |
} | |
// Throw the last exception if max retries are exceeded | |
if (response == null && lastException != null) { | |
throw lastException; | |
} | |
throw new IOException("No response and no last exception"); | |
} | |
private boolean isServerError(Response response) { | |
int statusCode = response.code(); | |
return statusCode >= 500 && statusCode < 600; | |
} | |
private boolean isTimeoutException(IOException e) { | |
return e instanceof SocketTimeoutException; | |
} | |
private void waitBeforeRetry(int attempt) { | |
Log.i(TAG, "Retrying request, attempt " + attempt + ", with " + retryStrategy + " strategy."); | |
long delay; | |
switch (retryStrategy) { | |
case EXPONENTIAL: | |
delay = (long) (retryDelayMillis * Math.pow(2, attempt - 1)); | |
break; | |
case LINEAR: | |
default: | |
delay = retryDelayMillis; | |
break; | |
} | |
try { | |
Thread.sleep(delay); | |
} catch (InterruptedException e) { | |
Thread.currentThread().interrupt(); | |
} | |
} | |
private static final String TAG = "RetryPolicy"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment