Skip to main content
Glama
connection-pool.ts5.6 kB
import { SQLiteClient } from '../rag/sqlite-client.js'; import { Logger, ConsoleLogger } from '../rag/sqlite-client.js'; import { MetricsCollector, NoOpMetrics } from '../rag/sqlite-client.js'; export interface ConnectionPoolConfig { dbPath?: string; logger?: Logger; metrics?: MetricsCollector; autoInitialize?: boolean; } export class ConnectionPool { private static instance: ConnectionPool | null = null; private sqliteClient: SQLiteClient | null = null; private isInitializing = false; private initPromise: Promise<void> | null = null; private readonly config: Required<ConnectionPoolConfig>; private readonly logger: Logger; private readonly metrics: MetricsCollector; private constructor(config: ConnectionPoolConfig = {}) { this.config = { dbPath: './data/rag.db', logger: new ConsoleLogger(), metrics: new NoOpMetrics(), autoInitialize: true, ...config }; this.logger = this.config.logger; this.metrics = this.config.metrics; } /** * Получить единственный экземпляр ConnectionPool (Singleton) */ public static getInstance(config?: ConnectionPoolConfig): ConnectionPool { if (!ConnectionPool.instance) { ConnectionPool.instance = new ConnectionPool(config); } return ConnectionPool.instance; } /** * Получить SQLiteClient, автоматически инициализируя его при необходимости */ public async getSQLiteClient(): Promise<SQLiteClient> { if (!this.sqliteClient) { await this.initialize(); } return this.sqliteClient!; } /** * Инициализировать пул соединений */ public async initialize(): Promise<void> { if (this.sqliteClient) { return; // Уже инициализирован } if (this.isInitializing) { // Дождаться завершения текущей инициализации if (this.initPromise) { await this.initPromise; return; } } this.isInitializing = true; this.initPromise = this.performInitialization(); try { await this.initPromise; } finally { this.isInitializing = false; this.initPromise = null; } } /** * Выполнить инициализацию */ private async performInitialization(): Promise<void> { try { this.logger.info('Initializing ConnectionPool', { dbPath: this.config.dbPath, autoInitialize: this.config.autoInitialize }); // Создаем SQLiteClient this.sqliteClient = new SQLiteClient( this.config.dbPath, this.logger, this.metrics ); // Инициализируем базу данных const initResult = await this.sqliteClient.initialize(); if (initResult.isErr()) { throw new Error(`Failed to initialize SQLiteClient: ${initResult.error.message}`); } this.logger.info('ConnectionPool initialized successfully'); this.metrics.recordOperation('connectionPool.initialize'); } catch (error) { const errorObj = error instanceof Error ? error : new Error(String(error)); this.logger.error('Failed to initialize ConnectionPool', errorObj); this.metrics.recordError('connectionPool.initialize'); // Сбрасываем состояние при ошибке this.sqliteClient = null; throw errorObj; } } /** * Проверить, инициализирован ли пул */ public isInitialized(): boolean { return this.sqliteClient !== null; } /** * Проверить подключение к базе данных */ public async isConnected(): Promise<boolean> { try { const client = await this.getSQLiteClient(); return await client.isConnected(); } catch { return false; } } /** * Получить статистику базы данных */ public async getStats() { try { const client = await this.getSQLiteClient(); return await client.getStats(); } catch (error) { const errorObj = error instanceof Error ? error : new Error(String(error)); this.logger.error('Failed to get database stats', errorObj); throw errorObj; } } /** * Закрыть все соединения */ public async close(): Promise<void> { if (this.sqliteClient) { try { await this.sqliteClient.close(); this.logger.info('ConnectionPool connections closed'); } catch (error) { const errorObj = error instanceof Error ? error : new Error(String(error)); this.logger.error('Error closing ConnectionPool', errorObj); } finally { this.sqliteClient = null; } } } /** * Сбросить пул (для тестов) */ public static reset(): void { if (ConnectionPool.instance) { ConnectionPool.instance.close(); ConnectionPool.instance = null; } } /** * Получить информацию о состоянии пула */ public getStatus() { return { isInitialized: this.isInitialized(), isInitializing: this.isInitializing, dbPath: this.config.dbPath, hasClient: !!this.sqliteClient }; } } // Экспортируем удобные функции export const getConnectionPool = (config?: ConnectionPoolConfig) => ConnectionPool.getInstance(config); export const resetConnectionPool = () => ConnectionPool.reset();

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/Galiusbro/MCP'

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