UNPKG

syntropylog

Version:

An instance manager with observability for Node.js applications

87 lines 4.26 kB
/** * FILE: src/http/HttpManager.ts * @description Manages the lifecycle and creation of multiple instrumented HTTP client instances. */ import { InstrumentedHttpClient } from './InstrumentedHttpClient'; import { errorToJsonValue } from '../types'; /** * @class HttpManager * @description Manages the creation and retrieval of multiple instrumented HTTP client instances. * It reads the configuration, creates an `InstrumentedHttpClient` for each defined * instance by wrapping the user-provided adapter, and provides a way to retrieve them. */ export class HttpManager { /** @private A map storing the created instrumented client instances by name. */ instances = new Map(); /** @private The logger instance for the manager itself. */ logger; /** @private A reference to the context manager for dependency injection. */ contextManager; /** @private The global application configuration. */ config; /** @private The name of the default HTTP client instance. */ defaultInstance; constructor(config, logger, contextManager) { this.config = config; this.logger = logger.child({ module: 'HttpManager' }); this.contextManager = contextManager; } init() { this.logger.trace('Initializing HttpManager...'); if (!this.config.instances || this.config.instances.length === 0) { this.logger.debug('HttpManager initialized, but no HTTP client instances were defined.'); return; } for (const instanceConfig of this.config.instances) { try { const client = new InstrumentedHttpClient(instanceConfig.adapter, this.logger, this.contextManager, instanceConfig); this.instances.set(instanceConfig.instanceName, client); this.logger.info(`HTTP client instance "${instanceConfig.instanceName}" created successfully via adapter.`); if (instanceConfig.isDefault) { if (this.defaultInstance) { this.logger.warn(`Multiple default HTTP instances defined. Overwriting previous default "${this.defaultInstance.instanceName}" with "${instanceConfig.instanceName}".`); } this.logger.trace(`Setting default HTTP instance: ${instanceConfig.instanceName}`); this.defaultInstance = client; } } catch (error) { this.logger.error({ error: errorToJsonValue(error) }, `Failed to create HTTP client instance "${instanceConfig.instanceName}"`); } } if (!this.defaultInstance && this.instances.size > 0) { const firstInstance = this.instances.values().next().value; const firstName = this.instances.keys().next().value; this.logger.trace(`No default HTTP instance configured. Using first available instance: ${firstName}`); this.defaultInstance = firstInstance; } } /** * Retrieves a managed and instrumented HTTP client instance by its name. * The returned client has a unified API via its `.request()` method. * @param {string} name - The name of the HTTP client instance to retrieve. * @returns {InstrumentedHttpClient} The requested client instance. * @throws {Error} If no instance with the given name is found. */ getInstance(name) { const instanceName = name ?? this.defaultInstance?.instanceName; if (!instanceName) { throw new Error('A specific instance name was not provided and no default HTTP instance is configured.'); } const instance = this.instances.get(instanceName); if (!instance) { throw new Error(`HTTP client instance with name "${instanceName}" was not found. Check your configuration.`); } return instance; } /** * Clears all managed HTTP client instances. This is a simple cleanup operation. */ async shutdown() { this.logger.info('Shutting down HTTP clients.'); this.instances.clear(); // HTTP clients do not require explicit shutdown, so we just clear the map. return Promise.resolve(); } } //# sourceMappingURL=HttpManager.js.map