From 95b8275b6f7ba00c67ecee06edc78378d8d2140b Mon Sep 17 00:00:00 2001 From: GEgorov Date: Tue, 7 Oct 2025 01:38:54 +0300 Subject: [PATCH] modified: backend/src/services/DatabasePoolManager.ts modified: backend/src/services/SqlExecutor.ts --- backend/src/services/DatabasePoolManager.ts | 8 +++-- backend/src/services/SqlExecutor.ts | 33 ++++++++++++++++++++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/backend/src/services/DatabasePoolManager.ts b/backend/src/services/DatabasePoolManager.ts index f13d3d4..6fc19ee 100644 --- a/backend/src/services/DatabasePoolManager.ts +++ b/backend/src/services/DatabasePoolManager.ts @@ -52,9 +52,11 @@ class DatabasePoolManager { user: dbConfig.username, password: dbConfig.password, ssl: dbConfig.ssl ? { rejectUnauthorized: false } : false, - max: 10, - idleTimeoutMillis: 30000, - connectionTimeoutMillis: 2000, + max: 20, // Увеличено количество соединений + idleTimeoutMillis: 60000, // 60 секунд + connectionTimeoutMillis: 10000, // 10 секунд (было 2 секунды) + keepAlive: true, // Поддерживать соединения активными + keepAliveInitialDelayMillis: 10000, // Начать keepAlive через 10 секунд }); pool.on('error', (err) => { diff --git a/backend/src/services/SqlExecutor.ts b/backend/src/services/SqlExecutor.ts index f8f9074..526fc2e 100644 --- a/backend/src/services/SqlExecutor.ts +++ b/backend/src/services/SqlExecutor.ts @@ -2,6 +2,33 @@ import { QueryResult } from '../types'; import { databasePoolManager } from './DatabasePoolManager'; export class SqlExecutor { + private async retryQuery( + fn: () => Promise, + retries: number = 3, + delay: number = 1000 + ): Promise { + for (let attempt = 1; attempt <= retries; attempt++) { + try { + return await fn(); + } catch (error: any) { + // Retry only on connection-related errors + const isConnectionError = + error.message?.includes('timeout') || + error.message?.includes('Connection terminated') || + error.message?.includes('ECONNREFUSED') || + error.message?.includes('ETIMEDOUT'); + + if (!isConnectionError || attempt === retries) { + throw error; + } + + console.warn(`Query attempt ${attempt} failed, retrying in ${delay}ms...`); + await new Promise(resolve => setTimeout(resolve, delay)); + } + } + throw new Error('Max retries exceeded'); + } + async executeQuery( databaseId: string, sqlQuery: string, @@ -19,7 +46,11 @@ export class SqlExecutor { // Security: Prevent multiple statements and dangerous commands this.validateQuery(sqlQuery); - const result = await pool.query(sqlQuery, params); + // Execute with retry mechanism + const result = await this.retryQuery(async () => { + return await pool.query(sqlQuery, params); + }, 3, 500); // 3 попытки с задержкой 500ms + const executionTime = Date.now() - startTime; return {