Skip to main content
Glama
project-instance-manager.ts9.1 kB
// Project-Specific Persistent Instance Manager // Gestisce istanze persistenti dedicate per ogni progetto Visum import { PersistentVisumController } from "./persistent-visum-controller.js"; interface ProjectConfig { name: string; projectPath: string; description: string; autoStart?: boolean; } interface ProjectInstance { config: ProjectConfig; controller: PersistentVisumController; isActive: boolean; startTime?: number; lastUsed?: number; stats?: { nodes: number; links: number; zones: number; }; } export class ProjectInstanceManager { private static instance: ProjectInstanceManager; private projectInstances: Map<string, ProjectInstance> = new Map(); // Configurazioni progetti predefinite private readonly PROJECT_CONFIGS: { [key: string]: ProjectConfig } = { campoleone: { name: "Campoleone", projectPath: "H:\\go\\italferr2025\\Campoleone\\100625_Versione_base_v0.3_sub_ok_priv.ver", description: "Progetto Campoleone - Rete ferroviaria principale", autoStart: true }, // Aggiungi altri progetti qui testProject: { name: "Test Project", projectPath: "H:\\path\\to\\test\\project.ver", description: "Progetto di test per sviluppo", autoStart: false } }; private constructor() { console.error("INIT: Project Instance Manager initialized"); } public static getInstance(): ProjectInstanceManager { if (!ProjectInstanceManager.instance) { ProjectInstanceManager.instance = new ProjectInstanceManager(); } return ProjectInstanceManager.instance; } /** * Avvia istanza persistente per progetto specifico */ public async startProjectInstance(projectId: string): Promise<{ success: boolean; message: string; stats?: any; }> { console.error(`🚀 Starting persistent instance for project: ${projectId}`); const config = this.PROJECT_CONFIGS[projectId]; if (!config) { return { success: false, message: `Unknown project ID: ${projectId}. Available: ${Object.keys(this.PROJECT_CONFIGS).join(', ')}` }; } // Verifica se l'istanza è già attiva if (this.projectInstances.has(projectId)) { const existing = this.projectInstances.get(projectId)!; if (existing.isActive) { return { success: true, message: `Project ${config.name} instance already running`, stats: existing.stats }; } } try { const startTime = Date.now(); // Crea controller personalizzato per questo progetto const controller = new PersistentVisumController(config.projectPath); const result = await controller.startPersistentVisumProcess(); if (result.success) { const projectInstance: ProjectInstance = { config, controller, isActive: true, startTime, lastUsed: Date.now(), stats: { nodes: result.nodes || 0, links: result.links || 0, zones: result.zones || 0 } }; this.projectInstances.set(projectId, projectInstance); console.error(`✅ Project ${config.name} instance started successfully`); console.error(` 📊 Network: ${result.nodes} nodes, ${result.links} links, ${result.zones} zones`); console.error(` ⏱️ Startup time: ${Date.now() - startTime}ms`); return { success: true, message: `Persistent instance for ${config.name} started successfully`, stats: projectInstance.stats }; } else { return { success: false, message: `Failed to start ${config.name}: ${result.message}` }; } } catch (error) { return { success: false, message: `Error starting ${config.name}: ${error instanceof Error ? error.message : String(error)}` }; } } /** * Esegue analisi complessa su istanza progetto specifica */ public async executeProjectAnalysis(projectId: string, analysisCode: string, description?: string): Promise<{ success: boolean; result?: any; error?: string; executionTimeMs?: number; projectInfo?: any; }> { const instance = this.projectInstances.get(projectId); if (!instance || !instance.isActive) { return { success: false, error: `Instance '${projectId}' is not active. Use 'project_start_instance' to start it first.` }; } return this.executeOnInstance(instance, analysisCode, description); } private async executeOnInstance(instance: ProjectInstance, analysisCode: string, description?: string): Promise<{ success: boolean; result?: any; error?: string; executionTimeMs?: number; projectInfo?: any; }> { try { instance.lastUsed = Date.now(); const result = await instance.controller.executeCustomCode(analysisCode, description); return { success: result.success, result: result.result, error: result.error, executionTimeMs: result.executionTimeMs, projectInfo: { projectName: instance.config.name, projectId: instance.config.name.toLowerCase(), stats: instance.stats } }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error) }; } } /** * Get status di tutte le istanze attive */ public getInstancesStatus(): { [projectId: string]: any } { const status: { [projectId: string]: any } = {}; for (const [projectId, instance] of this.projectInstances) { status[projectId] = { name: instance.config.name, description: instance.config.description, isActive: instance.isActive, startTime: instance.startTime, lastUsed: instance.lastUsed, uptime: instance.startTime ? Date.now() - instance.startTime : 0, stats: instance.stats }; } return status; } /** * Health check per istanza specifica */ public async checkProjectHealth(projectId: string): Promise<{ success: boolean; health?: any; error?: string; }> { const instance = this.projectInstances.get(projectId); if (!instance || !instance.isActive) { return { success: false, error: `Project instance ${projectId} not active` }; } try { const healthResult = await instance.controller.checkInstanceHealth(); return { success: healthResult.success, health: { ...healthResult.result, projectName: instance.config.name, uptime: Date.now() - (instance.startTime || Date.now()), lastUsed: instance.lastUsed }, error: healthResult.error }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error) }; } } /** * Shutdown istanza progetto specifica */ public async shutdownProjectInstance(projectId: string): Promise<{ success: boolean; message: string; }> { const instance = this.projectInstances.get(projectId); if (!instance) { return { success: false, message: `Project instance ${projectId} not found` }; } try { await instance.controller.shutdown(); instance.isActive = false; this.projectInstances.delete(projectId); console.error(`🔚 Project ${instance.config.name} instance shutdown completed`); return { success: true, message: `Project ${instance.config.name} instance shutdown successfully` }; } catch (error) { return { success: false, message: `Error shutting down ${instance.config.name}: ${error instanceof Error ? error.message : String(error)}` }; } } /** * Shutdown tutte le istanze */ public async shutdownAllInstances(): Promise<void> { console.error("🔚 Shutting down all project instances..."); const shutdownPromises = Array.from(this.projectInstances.keys()).map( projectId => this.shutdownProjectInstance(projectId) ); await Promise.all(shutdownPromises); console.error("✅ All project instances shutdown completed"); } /** * Auto-start istanze configurate per l'avvio automatico */ public async autoStartInstances(): Promise<void> { console.error("🚀 Auto-starting configured project instances..."); for (const [projectId, config] of Object.entries(this.PROJECT_CONFIGS)) { if (config.autoStart) { console.error(`⚡ Auto-starting ${config.name}...`); const result = await this.startProjectInstance(projectId); if (result.success) { console.error(`✅ ${config.name} auto-started successfully`); } else { console.error(`❌ Failed to auto-start ${config.name}: ${result.message}`); } } } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/multiluca2020/visum-thinker-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server