UNPKG

@push.rocks/smartproxy

Version:

A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.

158 lines 11.9 kB
/** * Manages timeouts and inactivity tracking for connections */ export class TimeoutManager { constructor(smartProxy) { this.smartProxy = smartProxy; } /** * Ensure timeout values don't exceed Node.js max safe integer */ ensureSafeTimeout(timeout) { const MAX_SAFE_TIMEOUT = 2147483647; // Maximum safe value (2^31 - 1) return Math.min(Math.floor(timeout), MAX_SAFE_TIMEOUT); } /** * Generate a slightly randomized timeout to prevent thundering herd */ randomizeTimeout(baseTimeout, variationPercent = 5) { const safeBaseTimeout = this.ensureSafeTimeout(baseTimeout); const variation = safeBaseTimeout * (variationPercent / 100); return this.ensureSafeTimeout(safeBaseTimeout + Math.floor(Math.random() * variation * 2) - variation); } /** * Update connection activity timestamp */ updateActivity(record) { record.lastActivity = Date.now(); // Clear any inactivity warning if (record.inactivityWarningIssued) { record.inactivityWarningIssued = false; } } /** * Calculate effective inactivity timeout based on connection type */ getEffectiveInactivityTimeout(record) { let effectiveTimeout = this.smartProxy.settings.inactivityTimeout || 14400000; // 4 hours default // For immortal keep-alive connections, use an extremely long timeout if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') { return Number.MAX_SAFE_INTEGER; } // For extended keep-alive connections, apply multiplier if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'extended') { const multiplier = this.smartProxy.settings.keepAliveInactivityMultiplier || 6; effectiveTimeout = effectiveTimeout * multiplier; } return this.ensureSafeTimeout(effectiveTimeout); } /** * Calculate effective max lifetime based on connection type */ getEffectiveMaxLifetime(record) { // Use route-specific timeout if available from the routeConfig const baseTimeout = record.routeConfig?.action.advanced?.timeout || this.smartProxy.settings.maxConnectionLifetime || 86400000; // 24 hours default // For immortal keep-alive connections, use an extremely long lifetime if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') { return Number.MAX_SAFE_INTEGER; } // For extended keep-alive connections, use the extended lifetime setting if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'extended') { return this.ensureSafeTimeout(this.smartProxy.settings.extendedKeepAliveLifetime || 7 * 24 * 60 * 60 * 1000 // 7 days default ); } // Apply randomization if enabled if (this.smartProxy.settings.enableRandomizedTimeouts) { return this.randomizeTimeout(baseTimeout); } return this.ensureSafeTimeout(baseTimeout); } /** * Setup connection timeout * @returns The cleanup timer */ setupConnectionTimeout(record, onTimeout) { // Clear any existing timer if (record.cleanupTimer) { clearTimeout(record.cleanupTimer); } // Skip timeout for immortal keep-alive connections if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') { return null; } // Calculate effective timeout const effectiveLifetime = this.getEffectiveMaxLifetime(record); // Set up the timeout const timer = setTimeout(() => { // Call the provided callback onTimeout(record, 'connection_timeout'); }, effectiveLifetime); // Make sure timeout doesn't keep the process alive if (timer.unref) { timer.unref(); } return timer; } /** * Check for inactivity on a connection * @returns Object with check results */ checkInactivity(record) { // Skip for connections with inactivity check disabled if (this.smartProxy.settings.disableInactivityCheck) { return { isInactive: false, shouldWarn: false, inactivityTime: 0, effectiveTimeout: 0 }; } // Skip for immortal keep-alive connections if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') { return { isInactive: false, shouldWarn: false, inactivityTime: 0, effectiveTimeout: 0 }; } const now = Date.now(); const inactivityTime = now - record.lastActivity; const effectiveTimeout = this.getEffectiveInactivityTimeout(record); // Check if inactive const isInactive = inactivityTime > effectiveTimeout; // For keep-alive connections, we should warn first const shouldWarn = record.hasKeepAlive && isInactive && !record.inactivityWarningIssued; return { isInactive, shouldWarn, inactivityTime, effectiveTimeout }; } /** * Apply socket timeout settings */ applySocketTimeouts(record) { // Skip for immortal keep-alive connections if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') { // Disable timeouts completely for immortal connections record.incoming.setTimeout(0); if (record.outgoing) { record.outgoing.setTimeout(0); } return; } // Apply normal timeouts const timeout = this.ensureSafeTimeout(this.smartProxy.settings.socketTimeout || 3600000); // 1 hour default record.incoming.setTimeout(timeout); if (record.outgoing) { record.outgoing.setTimeout(timeout); } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZW91dC1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvcHJveGllcy9zbWFydC1wcm94eS90aW1lb3V0LW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0E7O0dBRUc7QUFDSCxNQUFNLE9BQU8sY0FBYztJQUN6QixZQUFvQixVQUFzQjtRQUF0QixlQUFVLEdBQVYsVUFBVSxDQUFZO0lBQUcsQ0FBQztJQUU5Qzs7T0FFRztJQUNJLGlCQUFpQixDQUFDLE9BQWU7UUFDdEMsTUFBTSxnQkFBZ0IsR0FBRyxVQUFVLENBQUMsQ0FBQyxnQ0FBZ0M7UUFDckUsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxnQkFBZ0IsQ0FBQyxXQUFtQixFQUFFLG1CQUEyQixDQUFDO1FBQ3ZFLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUM1RCxNQUFNLFNBQVMsR0FBRyxlQUFlLEdBQUcsQ0FBQyxnQkFBZ0IsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUM3RCxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FDM0IsZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLFNBQVMsR0FBRyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQ3hFLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSSxjQUFjLENBQUMsTUFBeUI7UUFDN0MsTUFBTSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFakMsK0JBQStCO1FBQy9CLElBQUksTUFBTSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFDbkMsTUFBTSxDQUFDLHVCQUF1QixHQUFHLEtBQUssQ0FBQztRQUN6QyxDQUFDO0lB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