UNPKG

solver-sdk

Version:

SDK для интеграции с Code Solver Backend API

129 lines 6.21 kB
import { createWebSocketLogger } from './logger.js'; /** * Класс для управления состоянием подключений */ export class ConnectionStateManager { /** * Создает новый менеджер состояния подключений * @param {ConnectionStateManagerOptions} options Опции менеджера состояния подключений */ constructor(options = {}) { /** Хранилище состояний подключений */ this.states = new Map(); this.reconnectStrategy = options.reconnectStrategy || 'exponential'; this.retryDelay = options.retryDelay || 1000; this.maxRetryDelay = options.maxRetryDelay || 30000; this.logger = options.logger || createWebSocketLogger('ConnectionStateManager'); } /** * Получает состояние подключения для указанного пространства имен * @param {WebSocketNamespace} namespace Пространство имен * @returns {ConnectionState} Состояние подключения */ getState(namespace) { if (!this.states.has(namespace)) { // Инициализируем состояние по умолчанию this.states.set(namespace, { lastConnectTime: 0, reconnectAttempts: 0, connected: false, reconnecting: false }); } return this.states.get(namespace); } /** * Устанавливает состояние подключения для указанного пространства имен * @param {WebSocketNamespace} namespace Пространство имен * @param {boolean} connected Состояние подключения * @param {boolean} reconnecting Состояние переподключения */ setConnectionState(namespace, connected, reconnecting = false) { const state = this.getState(namespace); state.connected = connected; state.reconnecting = reconnecting; if (connected) { state.lastConnectTime = Date.now(); // Сбрасываем счетчик попыток переподключения, если успешно подключились if (!reconnecting) { state.reconnectAttempts = 0; } } this.states.set(namespace, state); this.logger.debug(`Обновлено состояние подключения для ${namespace}`, { connected, reconnecting, attempts: state.reconnectAttempts, lastConnect: state.lastConnectTime }); } /** * Увеличивает счетчик попыток переподключения для указанного пространства имен * @param {WebSocketNamespace} namespace Пространство имен * @returns {number} Новое количество попыток */ incrementReconnectAttempts(namespace) { const state = this.getState(namespace); state.reconnectAttempts++; state.reconnecting = true; this.states.set(namespace, state); this.logger.debug(`Увеличен счетчик попыток переподключения для ${namespace}`, { attempts: state.reconnectAttempts }); return state.reconnectAttempts; } /** * Рассчитывает задержку для переподключения на основе количества попыток и стратегии * @param {WebSocketNamespace} namespace Пространство имен * @returns {number} Задержка в миллисекундах */ calculateReconnectDelay(namespace) { const state = this.getState(namespace); const attempts = state.reconnectAttempts; if (this.reconnectStrategy === 'exponential') { // Экспоненциальный рост с фактором 1.5 const calculatedDelay = Math.min(this.retryDelay * Math.pow(1.5, attempts), this.maxRetryDelay); // Добавляем случайный фактор (jitter) для предотвращения штормов переподключений return calculatedDelay * (0.8 + Math.random() * 0.4); } else { // Линейный рост return Math.min(this.retryDelay * (attempts + 1), this.maxRetryDelay); } } /** * Сбрасывает счетчик попыток переподключения для указанного пространства имен * @param {WebSocketNamespace} namespace Пространство имен */ resetReconnectAttempts(namespace) { const state = this.getState(namespace); state.reconnectAttempts = 0; state.reconnecting = false; this.states.set(namespace, state); this.logger.debug(`Сброшен счетчик попыток переподключения для ${namespace}`); } /** * Регистрирует успешное подключение * @param {WebSocketNamespace} namespace Пространство имен */ registerSuccessfulConnection(namespace) { this.setConnectionState(namespace, true, false); this.resetReconnectAttempts(namespace); } /** * Регистрирует отключение * @param {WebSocketNamespace} namespace Пространство имен */ registerDisconnection(namespace) { this.setConnectionState(namespace, false, false); } /** * Регистрирует начало процесса переподключения * @param {WebSocketNamespace} namespace Пространство имен */ registerReconnecting(namespace) { this.setConnectionState(namespace, false, true); this.incrementReconnectAttempts(namespace); } } //# sourceMappingURL=connection-state-manager.js.map