Skip to content

Instantly share code, notes, and snippets.

@oleh-zaporozhets
Created October 23, 2021 18:55
Show Gist options
  • Save oleh-zaporozhets/ab956ddd05d1a689aa837eb3e625e85f to your computer and use it in GitHub Desktop.
Save oleh-zaporozhets/ab956ddd05d1a689aa837eb3e625e85f to your computer and use it in GitHub Desktop.
class CircuitBreakerWithEmitter implements ICircuitBreakerWithEmitter {
private readonly http: IHttp;
private readonly timeout: number;
private isOpen: boolean = false;
private readonly errorHandler: (error: any) => boolean;
private readonly eventEmitter: IEventEmitter;
constructor(http: IHttp, option: ICircuitBreakerOptions) {
this.http = http;
this.timeout = option.timeout;
this.errorHandler = option.errorHandler;
this.eventEmitter = new EventEmitter();
this.http.instance.interceptors.request.use(this.interceptRequest.bind(this));
this.http.instance.interceptors.response.use(
(response: AxiosResponse) => response,
this.interceptErrorResponse.bind(this),
);
}
public getStatus() {
return this.isOpen;
}
public on(event: CircuitBreakerEvents, listener: Function) {
this.eventEmitter.on(event, listener);
}
private interceptRequest(config: AxiosRequestConfig) {
const CancelToken = axios.CancelToken;
const cancelToken = new CancelToken((cancel) => cancel('Circuit breaker is open'));
return {
...config,
...(this.isOpen ? { cancelToken } : {}),
};
}
private interceptErrorResponse(error: any) {
const shouldCircuitBreakerBeOpen = this.errorHandler(error);
if (shouldCircuitBreakerBeOpen && !this.isOpen) {
this.openCircuitBreaker();
}
return Promise.reject(error);
}
private openCircuitBreaker() {
this.isOpen = true;
this.eventEmitter.emit('OPEN');
setTimeout(() => {
this.isOpen = false;
this.eventEmitter.emit('CLOSE');
}, this.timeout);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment