retry-axios
retry-axios copied to clipboard
Axios Timeout behaviour
We did not find any information about how the timeout acts when retry behaviour comes up.
given
axios.post(path, body, {
baseURL: ur;,
timeout: 12000,
raxConfig: {
retry: 5,
retryDelay: 500,
},
is the timeout of 12sec apply for all the 5 retries ? so 12 sec for performing 5 possible requests ? or for each retry, the timeout is reset to 12sec ? being possibly 12sec * 5 attempts ?
can you please introduce this documentation in the main README ?
@adrys-lab Use backoff : 'static' This will give static delay between retry. For the snippet you pasted. It will retry after 500ms
@anmol098 thanks for the backoff topic,
but i was talking about the general HTTP Timeout request when the server-side takes more than 12000 to respond.
My question is, if its a timeout for each retry, or by contrast, for ALL retries together.
Is there a way to make the axios
timeout NOT being reset to 0 for each retry ?
if we setup 10 seconds of timeout, we want to interpret it as a global value, so it is not used for each retry but for the whole request lifecycle.
Yeah, there's no way to do that directly through retry-axios
right now. The timeout
is passed directly to Axios, and taken into account for each retry. You'd need to tune the retries
variable to match the number you're looking for, otherwise you're going to get your timeout
and the retry logic fighting with each other.
Please consider adding a feature to restrict retries to the original request timeout. The competing axios-retry library has something along these lines under the shouldResetTimeout
option.
In the meantime, I have implemented something workable but kludgy via a retriesStopAtTimeout
option with following code, which I'll leave here in case it helps someone else:
const retryAxios = require("retry-axios");
const axiosClient = axios.create(config);
axiosClient.defaults.raxConfig = {
instance: axiosClient,
// Apply your default retry settings here..
/**
* HACK: Add and enforce option `retriesStopAtTimeout` which will prevent
* retry requests after the original Axios timeout. For example, if the
* timout was 2000, retry requests will only be sent within that 2 second
* timeframe (though the final request may finish after that time)
*/
retriesStopAtTimeout: true,
shouldRetry: function enforceRetriesStopAtTimeout(err) {
const raxConfig = retryAxios.getConfig(err);
// Ensure max retries is always respected
if (raxConfig.currentRetryAttempt >= raxConfig.retry) return false;
// Respect 'retry-axios' decision not to retry
if (!retryAxios.shouldRetryRequest(err)) {
return false;
}
// Only abort retries at timeout cutoff if configured to do so
if (!raxConfig.retriesStopAtTimeout) {
return true;
}
// This delay calculation is adapted from 'retry-axios' index.ts
let delay;
if (raxConfig.backoffType === "linear") {
delay = raxConfig.currentRetryAttempt * 1000;
} else if (raxConfig.backoffType === "static") {
delay = raxConfig.retryDelay;
} else {
delay = ((Math.pow(2, raxConfig.currentRetryAttempt) - 1) / 2) * 1000;
}
// Will the next retry request be sent before the retries cutoff?
raxConfig.nextRetryAvailableTime =
raxConfig.retriesStopAtTimeoutCutoff - Date.now() - delay;
// Don't retry request if there is no time for it to complete
if (raxConfig.nextRetryAvailableTime <= 0) {
return false;
}
return true;
},
};
retryAxios.attach(axiosClient);
/**
* HACK: Store the cutoff time to apply if `retriesStopAtTimeout` is set
* when the first request is sent.
*/
axiosClient.interceptors.request.use(
function storeRetriesStopAtTimeoutCutoff(config) {
const raxConfig = config.raxConfig || {};
if (!raxConfig.retriesStopAtTimeoutCutoff) {
raxConfig.retriesStopAtTimeoutCutoff = Date.now() + config.timeout;
}
return config;
},
undefined
);
Hi @JustinBeckwith , any update on this enhancement?