UNPKG

@duongtrungnguyen/nestro

Version:
157 lines 6.51 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __decorateClass = (decorators, target, key, kind) => { var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result; if (kind && result) __defProp(target, key, result); return result; }; var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index); var discovery_service_exports = {}; __export(discovery_service_exports, { DiscoveryService: () => DiscoveryService }); module.exports = __toCommonJS(discovery_service_exports); var import_common = require("@nestjs/common"); var import_common2 = require("../../common"); var import_constants = require("../constants"); var import_errors = require("../errors"); var import_loadbalancing = require("../loadbalancing"); var import_client = require("../../client"); let DiscoveryService = class { constructor(loadBalancingConfigs, loadBalancer, serverInfo) { this.loadBalancingConfigs = loadBalancingConfigs; this.loadBalancer = loadBalancer; this.services = /* @__PURE__ */ new Map(); this.serverBaseUrl = (0, import_common2.getServerURL)(serverInfo); } async onModuleInit() { (0, import_common2.debugLog)(DiscoveryService.name, "Initializing DiscoveryService..."); await this.loadInstances(); this.refreshIntervalId = setInterval(() => this.loadInstances(), this.loadBalancingConfigs.refreshInterval); } onModuleDestroy() { if (this.refreshIntervalId) { clearInterval(this.refreshIntervalId); } (0, import_common2.debugLog)(DiscoveryService.name, "DiscoveryService stopped"); } /** * Refreshes the service registry by fetching the latest instances from the server */ async loadInstances() { (0, import_common2.debugLog)(DiscoveryService.name, "Refreshing service registry"); try { const response = await fetch(`${this.serverBaseUrl}/nestro/services`, { method: "GET", headers: { "Content-Type": "application/json", Accept: "application/json" } }); if (!response.ok) { throw new Error(`Failed to fetch services: ${response.statusText}`); } const services = await response.json(); this.services.clear(); Object.entries(services).forEach(([serviceName, instances]) => { const activeInstances = instances.filter((instance) => instance.status === "ON"); if (activeInstances.length > 0) { this.services.set(serviceName, activeInstances); } }); (0, import_common2.debugLog)(DiscoveryService.name, `Registry refreshed with ${this.services.size} services`); } catch (error) { (0, import_common2.debugError)(DiscoveryService.name, `Failed to refresh registry: ${error.message}`); } } getServices() { return this.services; } /** * Gets all instances for a specific service */ getInstances(serviceName) { return this.services.get(serviceName) || []; } async discover(serviceName, callback) { const instances = this.getInstances(serviceName); if (!instances || instances.length === 0) { throw new import_errors.DiscoveryError(`Service ${serviceName} not found in registry`, import_errors.DiscoveryErrorCode.SERVICE_NOT_FOUND); } let lastError = null; const attemptedInstances = /* @__PURE__ */ new Set(); const maxRetries = instances.length; for (let attempt = 0; attempt < maxRetries; attempt++) { const remainingInstances = instances.filter((instance) => !attemptedInstances.has(this.getInstanceId(instance))); if (remainingInstances.length === 0) { break; } const selectedInstance = this.loadBalancer.selectInstance(remainingInstances); if (!selectedInstance) { break; } const instanceId = this.getInstanceId(selectedInstance); attemptedInstances.add(instanceId); if (this.loadBalancer.trackConnectionStart) { this.loadBalancer.trackConnectionStart(instanceId); } const startTime = Date.now(); let shouldRetry = false; const tryAnotherInstance = async () => { attemptedInstances.add(this.getInstanceId(selectedInstance)); if (this.loadBalancer.trackConnectionEnd) { this.loadBalancer.trackConnectionEnd(instanceId); } shouldRetry = true; }; try { const result = await callback(selectedInstance, tryAnotherInstance); if (this.loadBalancer instanceof import_loadbalancing.ResponseTimeStrategy) { const responseTime = Date.now() - startTime; this.loadBalancer.recordResponseTime(instanceId, responseTime); } if (!shouldRetry) { return result; } } catch (error) { if (!shouldRetry) { throw error; } } } if (lastError) throw lastError; throw new import_errors.DiscoveryError(`All instances for ${serviceName} service failed`, import_errors.DiscoveryErrorCode.ALL_INSTANCES_FAILED); } getInstanceId(instance) { return `${instance.name}:${instance.host}:${instance.port}`; } }; DiscoveryService = __decorateClass([ (0, import_common.Injectable)(), __decorateParam(0, (0, import_common.Inject)(import_constants.LOAD_BALANCING_CONFIGS)), __decorateParam(1, (0, import_common.Inject)(import_constants.LOAD_BALANCER)), __decorateParam(2, (0, import_common.Inject)(import_client.SERVER_INFO)) ], DiscoveryService); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { DiscoveryService }); //# sourceMappingURL=discovery.service.js.map