Skip to content

Commit

Permalink
feat: limit retries and use exponential backoff for api requests (#203)
Browse files Browse the repository at this point in the history
  • Loading branch information
hunterckx committed Oct 9, 2024
1 parent a7027b3 commit 93cfff1
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions src/entity/common/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,34 @@ import axios, {
} from "axios";
import { getURL } from "../../shared/utils";

let axiosInstance: AxiosInstance | null = null;
const MAX_RETRIES = 3;
const INITIAL_RETRY = 1000;
const RETRY_BACKOFF = 3;

/**
* Adding response interceptors to axios instances.
* @param api - AxiosInstance.
*/
export const configureInterceptors = (api: AxiosInstance): void => {
let nextRetryInterval = INITIAL_RETRY;
let retryCount = 0;
api.interceptors.response.use(
(response: AxiosResponse) => response,
(error: AxiosError) => {
const { config, response } = error;

if (response?.status === HttpStatusCode.ServiceUnavailable && config) {
if (
response?.status === HttpStatusCode.ServiceUnavailable &&
config &&
retryCount < MAX_RETRIES
) {
const retryAfterValue = response.headers["Retry-After"];
const waitingTime = retryAfterValue ? +retryAfterValue : 0;
let waitingTime = Number(retryAfterValue);
if (isNaN(waitingTime) || waitingTime <= 0) {
waitingTime = nextRetryInterval;
nextRetryInterval *= RETRY_BACKOFF;
}
retryCount++;
return new Promise((resolve) => {
setTimeout(() => resolve(api(config)), waitingTime);
});
Expand All @@ -32,17 +45,15 @@ export const configureInterceptors = (api: AxiosInstance): void => {
};

/**
* Returns a singleton Axios instance configured for making HTTP requests to a specified base URL.
* Returns an Axios instance configured for making HTTP requests to a specified base URL.
* @param baseURL - The base URL to use for the AxiosInstance.
* @returns axios instance.
*/
export const api = (baseURL = getURL()): AxiosInstance => {
if (!axiosInstance) {
axiosInstance = axios.create({
baseURL,
timeout: 20 * 1000,
});
configureInterceptors(axiosInstance);
}
const axiosInstance = axios.create({
baseURL,
timeout: 20 * 1000,
});
configureInterceptors(axiosInstance);
return axiosInstance;
};

0 comments on commit 93cfff1

Please sign in to comment.