Enhance database connection management by introducing configurable pool settings and implementing a retry mechanism for transient connection issues. Updated Sequelize pool options to use environment variables for better flexibility and added a retry wrapper for initializing settings to handle connection timeouts gracefully.
This commit is contained in:
@@ -38,6 +38,12 @@ if (!dbName || !dbUser || !dbHost) {
|
|||||||
throw new Error('Missing required database environment variables: DB_NAME, DB_USER, or DB_HOST');
|
throw new Error('Missing required database environment variables: DB_NAME, DB_USER, or DB_HOST');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const poolMax = Number.parseInt(process.env.DB_POOL_MAX || '5', 10);
|
||||||
|
const poolMin = Number.parseInt(process.env.DB_POOL_MIN || '1', 10);
|
||||||
|
const poolAcquire = Number.parseInt(process.env.DB_POOL_ACQUIRE || '30000', 10);
|
||||||
|
const poolIdle = Number.parseInt(process.env.DB_POOL_IDLE || '10000', 10);
|
||||||
|
const poolEvict = Number.parseInt(process.env.DB_POOL_EVICT || '1000', 10);
|
||||||
|
|
||||||
const sequelize = new Sequelize(dbName, dbUser, dbPass, {
|
const sequelize = new Sequelize(dbName, dbUser, dbPass, {
|
||||||
host: dbHost,
|
host: dbHost,
|
||||||
dialect: 'postgres',
|
dialect: 'postgres',
|
||||||
@@ -48,11 +54,11 @@ const sequelize = new Sequelize(dbName, dbUser, dbPass, {
|
|||||||
benchmark: SQL_BENCHMARK,
|
benchmark: SQL_BENCHMARK,
|
||||||
logging: sqlLogger,
|
logging: sqlLogger,
|
||||||
pool: {
|
pool: {
|
||||||
max: 5, // Maximale Anzahl von Verbindungen im Pool (reduziert, um Connection Limit zu vermeiden)
|
max: poolMax, // Maximale Anzahl von Verbindungen im Pool
|
||||||
min: 1, // Minimale Anzahl von Verbindungen im Pool
|
min: poolMin, // Minimale Anzahl von Verbindungen im Pool
|
||||||
acquire: 30000, // Maximale Zeit (ms) zum Erwerb einer Verbindung (30 Sekunden)
|
acquire: poolAcquire, // Maximale Zeit (ms) zum Erwerb einer Verbindung
|
||||||
idle: 10000, // Maximale Zeit (ms), die eine Verbindung idle sein kann, bevor sie entfernt wird
|
idle: poolIdle, // Maximale Zeit (ms), die eine Verbindung idle sein kann, bevor sie entfernt wird
|
||||||
evict: 1000, // Intervall (ms) zum Prüfen auf idle Verbindungen
|
evict: poolEvict, // Intervall (ms) zum Prüfen auf idle Verbindungen
|
||||||
handleDisconnects: true // Automatisches Reconnect bei Verbindungsverlust
|
handleDisconnects: true // Automatisches Reconnect bei Verbindungsverlust
|
||||||
},
|
},
|
||||||
dialectOptions: {
|
dialectOptions: {
|
||||||
|
|||||||
@@ -23,6 +23,27 @@ const queryWithTimeout = async (query, timeoutMs = 30000, description = 'Query')
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Helper: Retry wrapper for transient pool/connection issues
|
||||||
|
const runWithRetry = async (fn, { retries = 3, delayMs = 2000, description = 'operation' } = {}) => {
|
||||||
|
let lastError;
|
||||||
|
for (let attempt = 1; attempt <= retries; attempt++) {
|
||||||
|
try {
|
||||||
|
return await fn();
|
||||||
|
} catch (error) {
|
||||||
|
lastError = error;
|
||||||
|
const isAcquireTimeout = error?.name === 'SequelizeConnectionAcquireTimeoutError'
|
||||||
|
|| error?.message?.includes('ConnectionAcquireTimeoutError')
|
||||||
|
|| error?.message?.includes('Operation timeout');
|
||||||
|
if (!isAcquireTimeout || attempt === retries) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
console.warn(`⚠️ ${description} fehlgeschlagen (AcquireTimeout). Retry ${attempt}/${retries} in ${delayMs}ms...`);
|
||||||
|
await new Promise(resolve => setTimeout(resolve, delayMs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw lastError;
|
||||||
|
};
|
||||||
|
|
||||||
// Helper: Prüft ob Tabelle existiert
|
// Helper: Prüft ob Tabelle existiert
|
||||||
const tableExists = async (schema, tableName) => {
|
const tableExists = async (schema, tableName) => {
|
||||||
try {
|
try {
|
||||||
@@ -592,7 +613,10 @@ const syncDatabase = async () => {
|
|||||||
await syncModelsWithUpdates(models);
|
await syncModelsWithUpdates(models);
|
||||||
|
|
||||||
console.log("Initializing settings...");
|
console.log("Initializing settings...");
|
||||||
await initializeSettings();
|
await runWithRetry(
|
||||||
|
() => initializeSettings(),
|
||||||
|
{ retries: 3, delayMs: 2000, description: 'initializeSettings' }
|
||||||
|
);
|
||||||
|
|
||||||
console.log("Initializing types...");
|
console.log("Initializing types...");
|
||||||
await initializeTypes();
|
await initializeTypes();
|
||||||
|
|||||||
Reference in New Issue
Block a user