Skip to content

Instantly share code, notes, and snippets.

@mtorre4580
Created April 9, 2023 02:32
Show Gist options
  • Save mtorre4580/17ef9120aafe5e1f5dbdf4a186c84229 to your computer and use it in GitHub Desktop.
Save mtorre4580/17ef9120aafe5e1f5dbdf4a186c84229 to your computer and use it in GitHub Desktop.
Example http-client with circuit breaker support and keep alive connection with axios in Node.js
const axios = require("axios");
const Agent = require("agentkeepalive");
const CircuitBreaker = require("opossum");
// Replace with your configs
const TIMEOUT_DEFAULT = 2500;
const MAX_SOCKETS = 100;
const MAX_FREE_SOCKET = 10;
const TIME_OUT_KEEP_ALIVE = 60000;
const FREE_SOCKET_TIMEOUT = 30000;
const RESET_TIMEOUT_CIRCUIT_BREAKER = 15000;
const ERROR_THRESHOLD_PERCENT_CIRCUIT_BREAKER = 25;
// Replace with your logger
const logger = console;
/**
* Create the configuration for agent http
* @returns {object}
*/
function createHttpAgent() {
return new Agent({
maxSockets: MAX_SOCKETS,
maxFreeSockets: MAX_FREE_SOCKET,
timeout: TIME_OUT_KEEP_ALIVE,
freeSocketTimeout: FREE_SOCKET_TIMEOUT,
});
}
/**
* Create the configuration for agent https
* @returns {object}
*/
function createHttpsAgent() {
return new Agent.HttpsAgent({
maxSockets: MAX_SOCKETS,
maxFreeSockets: MAX_FREE_SOCKET,
timeout: TIME_OUT_KEEP_ALIVE,
freeSocketTimeout: FREE_SOCKET_TIMEOUT,
});
}
/**
* Create an instance with axios with keep alive feature
* @param {object} config
* @returns {object}
*/
function createInstance(config) {
const httpClient = axios.create(config || { timeout: TIMEOUT_DEFAULT });
httpClient.defaults.httpAgent = createHttpAgent();
httpClient.defaults.httpsAgent = createHttpsAgent();
return httpClient;
}
/**
* Create an instance for the circuit breaker for any method
* @param {Function} handler
* @param {object} options
* @returns CircuitBreaker
*/
function createCircuitBreaker(handler, options) {
const circuitBreaker = new CircuitBreaker(handler, {
resetTimeout: RESET_TIMEOUT_CIRCUIT_BREAKER,
errorThresholdPercentage: ERROR_THRESHOLD_PERCENT_CIRCUIT_BREAKER,
timeout: TIMEOUT_DEFAULT,
errorFilter: (err) => err.statusCode !== 401 || err.statusCode !== 403,
...options,
});
circuitBreaker.on("halfOpen", () => {
logger.warn(
`The Circuit Breaker is "HALF_OPEN" for "${circuitBreaker.name}"`
);
});
circuitBreaker.on("open", () => {
logger.error(`The Circuit Breaker is "OPEN" for "${circuitBreaker.name}"`);
});
circuitBreaker.on("success", (response) => {
logger.debug(`API response: ${JSON.stringify(response, null, 2)}`);
});
return circuitBreaker;
}
// Example using the instance axios with the circuit breaker support
// Only for check, remove
(async () => {
async function getCountryArgentina() {
const { data } = await axiosInstance.get(
`https://restcountries.com/v3.1/name/argentina`,
{
params: { fields: "name, capital, flag" },
}
);
return data;
}
const axiosInstance = createInstance();
const circuitBreaker = createCircuitBreaker(getCountryArgentina);
await circuitBreaker.fire();
})();
module.exports = { createInstance, createCircuitBreaker };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment