UNPKG

amazon-seller-mcp

Version:

Model Context Protocol (MCP) client for Amazon Selling Partner API

251 lines 7.28 kB
/** * Connection pool manager for Amazon Seller MCP Client * * This file implements connection pooling for HTTP requests to improve performance: * - Reuse HTTP connections * - Limit concurrent connections * - Connection timeout management * - Connection health monitoring */ // Node.js built-ins import http from 'http'; import https from 'https'; // Internal imports import * as logger from './logger.js'; /** * Connection pool manager for HTTP requests */ export class ConnectionPool { /** * HTTP agent for connection pooling */ httpAgent; /** * HTTPS agent for connection pooling */ httpsAgent; /** * Connection pool configuration */ config; /** * Connection pool statistics */ stats = { activeSockets: 0, freeSockets: 0, queuedRequests: 0, totalRequests: 0, timeouts: 0, errors: 0, }; /** * Create a new connection pool * * @param config Connection pool configuration */ constructor(config = {}) { // Set default configuration this.config = { maxSockets: config.maxSockets ?? 10, maxFreeSockets: config.maxFreeSockets ?? 5, timeout: config.timeout ?? 60000, keepAliveTimeout: config.keepAliveTimeout ?? 60000, keepAlive: config.keepAlive ?? true, }; // Create HTTP agent this.httpAgent = new http.Agent({ keepAlive: this.config.keepAlive, keepAliveMsecs: this.config.keepAliveTimeout, maxSockets: this.config.maxSockets, maxFreeSockets: this.config.maxFreeSockets, timeout: this.config.timeout, }); // Create HTTPS agent this.httpsAgent = new https.Agent({ keepAlive: this.config.keepAlive, keepAliveMsecs: this.config.keepAliveTimeout, maxSockets: this.config.maxSockets, maxFreeSockets: this.config.maxFreeSockets, timeout: this.config.timeout, }); // Log connection pool initialization logger.debug('Connection pool initialized', { maxSockets: this.config.maxSockets, maxFreeSockets: this.config.maxFreeSockets, timeout: this.config.timeout, keepAliveTimeout: this.config.keepAliveTimeout, keepAlive: this.config.keepAlive, }); // Start monitoring connections this.startMonitoring(); } /** * Get the HTTP agent * * @returns HTTP agent */ getHttpAgent() { return this.httpAgent; } /** * Get the HTTPS agent * * @returns HTTPS agent */ getHttpsAgent() { return this.httpsAgent; } /** * Get connection pool statistics * * @returns Connection pool statistics */ getStats() { return { ...this.stats }; } /** * Update connection pool statistics */ updateStats() { // Update HTTP agent stats const httpSockets = this.httpAgent.sockets; const httpFreeSockets = this.httpAgent.freeSockets; const httpRequests = this.httpAgent.requests; // Update HTTPS agent stats const httpsSockets = this.httpsAgent.sockets; const httpsFreeSockets = this.httpsAgent.freeSockets; const httpsRequests = this.httpsAgent.requests; // Count active sockets let activeSockets = 0; for (const key in httpSockets) { activeSockets += httpSockets[key]?.length || 0; } for (const key in httpsSockets) { activeSockets += httpsSockets[key]?.length || 0; } // Count free sockets let freeSockets = 0; for (const key in httpFreeSockets) { freeSockets += httpFreeSockets[key]?.length || 0; } for (const key in httpsFreeSockets) { freeSockets += httpsFreeSockets[key]?.length || 0; } // Count queued requests let queuedRequests = 0; for (const key in httpRequests) { queuedRequests += httpRequests[key]?.length || 0; } for (const key in httpsRequests) { queuedRequests += httpsRequests[key]?.length || 0; } // Update stats this.stats.activeSockets = activeSockets; this.stats.freeSockets = freeSockets; this.stats.queuedRequests = queuedRequests; } /** * Start monitoring connections */ startMonitoring() { // Update stats every 10 seconds setInterval(() => { this.updateStats(); // Log connection pool stats logger.debug('Connection pool stats', { activeSockets: this.stats.activeSockets, freeSockets: this.stats.freeSockets, queuedRequests: this.stats.queuedRequests, totalRequests: this.stats.totalRequests, timeouts: this.stats.timeouts, errors: this.stats.errors, }); }, 10000); // Monitor socket events this.monitorSocketEvents(); } /** * Monitor socket events */ monitorSocketEvents() { // Monitor HTTP agent this.httpAgent.on('free', () => { this.updateStats(); }); this.httpAgent.on('timeout', () => { this.stats.timeouts++; this.updateStats(); }); this.httpAgent.on('error', () => { this.stats.errors++; this.updateStats(); }); // Monitor HTTPS agent this.httpsAgent.on('free', () => { this.updateStats(); }); this.httpsAgent.on('timeout', () => { this.stats.timeouts++; this.updateStats(); }); this.httpsAgent.on('error', () => { this.stats.errors++; this.updateStats(); }); } /** * Track a new request */ trackRequest() { this.stats.totalRequests++; } /** * Close all connections */ destroy() { this.httpAgent.destroy(); this.httpsAgent.destroy(); logger.debug('Connection pool destroyed'); } } /** * Default connection pool instance */ let defaultConnectionPool; /** * Configure the default connection pool * * @param config Connection pool configuration */ export function configureConnectionPool(config) { // Destroy existing connection pool if it exists if (defaultConnectionPool) { defaultConnectionPool.destroy(); } // Create new connection pool defaultConnectionPool = new ConnectionPool(config); } /** * Initialize default connection pool if not already initialized */ function ensureDefaultConnectionPool() { if (!defaultConnectionPool) { defaultConnectionPool = new ConnectionPool(); } } /** * Get the default connection pool instance * * @returns Default connection pool instance */ export function getConnectionPool() { ensureDefaultConnectionPool(); return defaultConnectionPool; } export default { ConnectionPool, configureConnectionPool, getConnectionPool, }; //# sourceMappingURL=connection-pool.js.map