import type { Logger } from "@atbb/logger"; /** * Manages reconnection attempts with exponential backoff. * * Implements a backoff strategy where each retry is delayed by * baseDelay * 2^(attempt - 1), providing increasing delays between * reconnection attempts to avoid overwhelming the service. */ export class ReconnectionManager { private attempts = 0; /** * @param maxAttempts - Maximum number of reconnection attempts * @param baseDelayMs - Base delay in milliseconds (will be exponentially increased) */ constructor( private maxAttempts: number, private baseDelayMs: number, private logger: Logger ) {} /** * Attempt to reconnect with exponential backoff * * @param reconnectFn - Function to call to perform the reconnection * @throws Error if max attempts exceeded */ async attemptReconnect(reconnectFn: () => Promise): Promise { if (this.attempts >= this.maxAttempts) { this.logger.fatal("Max reconnect attempts reached - manual intervention required", { maxAttempts: this.maxAttempts, }); throw new Error('Max reconnection attempts exceeded'); } this.attempts++; const delay = this.baseDelayMs * Math.pow(2, this.attempts - 1); this.logger.info("Attempting to reconnect", { attempt: this.attempts, maxAttempts: this.maxAttempts, delayMs: delay, }); await this.sleep(delay); await reconnectFn(); } /** * Reset the attempt counter (call on successful connection) */ reset(): void { this.attempts = 0; } /** * Get current attempt count for monitoring */ getAttemptCount(): number { return this.attempts; } /** * Sleep for specified milliseconds */ private sleep(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)); } }