reactbits-mcp-server
Version:
MCP Server for React Bits - Access 99+ React components with animations, backgrounds, and UI elements
117 lines (116 loc) • 3.33 kB
JavaScript
import { logWarning, logInfo } from './logger.js';
/**
* Circuit breaker states
*/
var CircuitBreakerState;
(function (CircuitBreakerState) {
CircuitBreakerState["CLOSED"] = "CLOSED";
CircuitBreakerState["OPEN"] = "OPEN";
CircuitBreakerState["HALF_OPEN"] = "HALF_OPEN";
})(CircuitBreakerState || (CircuitBreakerState = {}));
/**
* Circuit breaker implementation for protecting external calls
*/
class CircuitBreaker {
state = CircuitBreakerState.CLOSED;
failureCount = 0;
lastFailureTime = 0;
config;
constructor(config) {
this.config = config;
}
/**
* Execute a function with circuit breaker protection
* @param fn - Function to execute
* @returns Promise with the result
*/
async execute(fn) {
if (this.state === CircuitBreakerState.OPEN) {
if (this.shouldAttemptReset()) {
this.state = CircuitBreakerState.HALF_OPEN;
logInfo('Circuit breaker transitioning to HALF_OPEN state');
}
else {
throw new Error('Circuit breaker is OPEN - request rejected');
}
}
try {
const result = await fn();
this.onSuccess();
return result;
}
catch (error) {
this.onFailure();
throw error;
}
}
/**
* Handle successful execution
*/
onSuccess() {
this.failureCount = 0;
if (this.state === CircuitBreakerState.HALF_OPEN) {
this.state = CircuitBreakerState.CLOSED;
logInfo('Circuit breaker reset to CLOSED state');
}
}
/**
* Handle failed execution
*/
onFailure() {
this.failureCount++;
this.lastFailureTime = Date.now();
if (this.failureCount >= this.config.failureThreshold) {
this.state = CircuitBreakerState.OPEN;
logWarning(`Circuit breaker opened after ${this.failureCount} failures`);
}
}
/**
* Check if we should attempt to reset the circuit breaker
* @returns True if we should attempt reset
*/
shouldAttemptReset() {
return Date.now() - this.lastFailureTime >= this.config.recoveryTimeout;
}
/**
* Get current circuit breaker state
* @returns Current state
*/
getState() {
return this.state;
}
/**
* Get failure count
* @returns Current failure count
*/
getFailureCount() {
return this.failureCount;
}
/**
* Reset the circuit breaker manually
*/
reset() {
this.state = CircuitBreakerState.CLOSED;
this.failureCount = 0;
this.lastFailureTime = 0;
logInfo('Circuit breaker manually reset');
}
}
/**
* Circuit breaker instances for different types of operations
*/
export const circuitBreakers = {
// For external API calls (GitHub, etc.)
external: new CircuitBreaker({
failureThreshold: 5,
recoveryTimeout: 60000, // 1 minute
monitoringPeriod: 10000 // 10 seconds
}),
// For file system operations
filesystem: new CircuitBreaker({
failureThreshold: 3,
recoveryTimeout: 30000, // 30 seconds
monitoringPeriod: 5000 // 5 seconds
})
};
export { CircuitBreaker, CircuitBreakerState };