const PackageDiscovery = require('./PackageDiscovery') const ProjectDiscovery = require('./ProjectDiscovery') /** * DiscoveryManager - 资源发现管理器 * * 统一管理多个资源发现器,按照文档架构设计: * 1. 按优先级排序发现器 (数字越小优先级越高) * 2. 并行执行资源发现 * 3. 收集并合并所有发现的资源 * 4. 提供容错机制,单个发现器失败不影响整体 */ class DiscoveryManager { /** * 构造函数 * @param {Array} discoveries - 自定义发现器列表,如果不提供则使用默认配置 */ constructor(discoveries = null) { if (discoveries) { this.discoveries = [...discoveries] } else { // 默认发现器配置:只包含包级和项目级发现 this.discoveries = [ new PackageDiscovery(), // 优先级: 1 new ProjectDiscovery() // 优先级: 2 ] } // 按优先级排序 this._sortDiscoveriesByPriority() } /** * 添加发现器 * @param {Object} discovery - 实现了发现器接口的对象 */ addDiscovery(discovery) { if (!discovery || typeof discovery.discover !== 'function') { throw new Error('Discovery must implement discover method') } this.discoveries.push(discovery) this._sortDiscoveriesByPriority() } /** * 移除发现器 * @param {string} source - 发现器源类型 */ removeDiscovery(source) { this.discoveries = this.discoveries.filter(discovery => discovery.source !== source) } /** * 发现所有资源(并行模式) * @returns {Promise} 所有发现的资源列表 */ async discoverAll() { const discoveryPromises = this.discoveries.map(async (discovery) => { try { const resources = await discovery.discover() return Array.isArray(resources) ? resources : [] } catch (error) { console.warn(`[DiscoveryManager] ${discovery.source} discovery failed: ${error.message}`) return [] } }) // 并行执行所有发现器 const discoveryResults = await Promise.allSettled(discoveryPromises) // 收集所有成功的结果 const allResources = [] discoveryResults.forEach((result, index) => { if (result.status === 'fulfilled') { allResources.push(...result.value) } else { console.warn(`[DiscoveryManager] ${this.discoveries[index].source} discovery rejected: ${result.reason}`) } }) return allResources } /** * 发现并合并所有注册表(新架构方法) * @returns {Promise} 合并后的资源注册表 Map */ async discoverRegistries() { const registryPromises = this.discoveries.map(async (discovery) => { try { // 优先使用新的discoverRegistry方法 if (typeof discovery.discoverRegistry === 'function') { const registry = await discovery.discoverRegistry() return registry instanceof Map ? registry : new Map() } else { // 向后兼容:将discover()结果转换为注册表格式 const resources = await discovery.discover() const registry = new Map() if (Array.isArray(resources)) { resources.forEach(resource => { if (resource.id && resource.reference) { registry.set(resource.id, resource.reference) } }) } return registry } } catch (error) { console.warn(`[DiscoveryManager] ${discovery.source} registry discovery failed: ${error.message}`) return new Map() } }) // 并行执行所有发现器 const registryResults = await Promise.allSettled(registryPromises) // 收集所有成功的注册表 const registries = [] registryResults.forEach((result, index) => { if (result.status === 'fulfilled') { registries.push(result.value) } else { console.warn(`[DiscoveryManager] ${this.discoveries[index].source} registry discovery rejected: ${result.reason}`) registries.push(new Map()) } }) // 按发现器优先级合并注册表 return this._mergeRegistries(registries) } /** * 按源类型发现注册表 * @param {string} source - 发现器源类型 * @returns {Promise} 指定源的资源注册表 */ async discoverRegistryBySource(source) { const discovery = this._findDiscoveryBySource(source) if (!discovery) { throw new Error(`Discovery source ${source} not found`) } if (typeof discovery.discoverRegistry === 'function') { return await discovery.discoverRegistry() } else { // 向后兼容:将discover()结果转换为注册表格式 const resources = await discovery.discover() const registry = new Map() if (Array.isArray(resources)) { resources.forEach(resource => { if (resource.id && resource.reference) { registry.set(resource.id, resource.reference) } }) } return registry } } /** * 按源类型发现资源 * @param {string} source - 发现器源类型 * @returns {Promise} 指定源的资源列表 */ async discoverBySource(source) { const discovery = this._findDiscoveryBySource(source) if (!discovery) { throw new Error(`Discovery source ${source} not found`) } return await discovery.discover() } /** * 获取所有发现器信息 * @returns {Array} 发现器信息列表 */ getDiscoveryInfo() { return this.discoveries.map(discovery => { if (typeof discovery.getDiscoveryInfo === 'function') { return discovery.getDiscoveryInfo() } else { return { source: discovery.source || 'UNKNOWN', priority: discovery.priority || 0, description: 'No description available' } } }) } /** * 清理所有发现器缓存 */ clearCache() { this.discoveries.forEach(discovery => { if (typeof discovery.clearCache === 'function') { discovery.clearCache() } }) } /** * 获取发现器数量 * @returns {number} 注册的发现器数量 */ getDiscoveryCount() { return this.discoveries.length } /** * 合并多个注册表 * @param {Array} registries - 注册表数组,按优先级排序(数字越小优先级越高) * @returns {Map} 合并后的注册表 * @private */ _mergeRegistries(registries) { const mergedRegistry = new Map() // 从后往前合并:先添加低优先级的,再让高优先级的覆盖 // registries按优先级升序排列 [high(0), med(1), low(2)] // 我们从低优先级开始,让高优先级的覆盖 for (let i = registries.length - 1; i >= 0; i--) { const registry = registries[i] if (registry instanceof Map) { for (const [key, value] of registry) { mergedRegistry.set(key, value) // 直接设置,让高优先级的最终覆盖 } } } return mergedRegistry } /** * 按优先级排序发现器 * @private */ _sortDiscoveriesByPriority() { this.discoveries.sort((a, b) => { const priorityA = a.priority || 0 const priorityB = b.priority || 0 return priorityA - priorityB // 升序排序,数字越小优先级越高 }) } /** * 根据源类型查找发现器 * @param {string} source - 发现器源类型 * @returns {Object|undefined} 找到的发现器或undefined * @private */ _findDiscoveryBySource(source) { return this.discoveries.find(discovery => discovery.source === source) } } module.exports = DiscoveryManager