WIP! A BB-style forum, on the ATmosphere! We're still working... we'll be back soon when we have something to show off!
node typescript hono htmx atproto
at root/atb-56-theme-caching-layer 70 lines 1.9 kB view raw
1import type { Logger } from "@atbb/logger"; 2 3/** 4 * Manages reconnection attempts with exponential backoff. 5 * 6 * Implements a backoff strategy where each retry is delayed by 7 * baseDelay * 2^(attempt - 1), providing increasing delays between 8 * reconnection attempts to avoid overwhelming the service. 9 */ 10export class ReconnectionManager { 11 private attempts = 0; 12 13 /** 14 * @param maxAttempts - Maximum number of reconnection attempts 15 * @param baseDelayMs - Base delay in milliseconds (will be exponentially increased) 16 */ 17 constructor( 18 private maxAttempts: number, 19 private baseDelayMs: number, 20 private logger: Logger 21 ) {} 22 23 /** 24 * Attempt to reconnect with exponential backoff 25 * 26 * @param reconnectFn - Function to call to perform the reconnection 27 * @throws Error if max attempts exceeded 28 */ 29 async attemptReconnect(reconnectFn: () => Promise<void>): Promise<void> { 30 if (this.attempts >= this.maxAttempts) { 31 this.logger.fatal("Max reconnect attempts reached - manual intervention required", { 32 maxAttempts: this.maxAttempts, 33 }); 34 throw new Error('Max reconnection attempts exceeded'); 35 } 36 37 this.attempts++; 38 const delay = this.baseDelayMs * Math.pow(2, this.attempts - 1); 39 40 this.logger.info("Attempting to reconnect", { 41 attempt: this.attempts, 42 maxAttempts: this.maxAttempts, 43 delayMs: delay, 44 }); 45 46 await this.sleep(delay); 47 await reconnectFn(); 48 } 49 50 /** 51 * Reset the attempt counter (call on successful connection) 52 */ 53 reset(): void { 54 this.attempts = 0; 55 } 56 57 /** 58 * Get current attempt count for monitoring 59 */ 60 getAttemptCount(): number { 61 return this.attempts; 62 } 63 64 /** 65 * Sleep for specified milliseconds 66 */ 67 private sleep(ms: number): Promise<void> { 68 return new Promise(resolve => setTimeout(resolve, ms)); 69 } 70}