Files
miriamgemeinde/utils/withDbRetries.js

52 lines
1.4 KiB
JavaScript

const sequelize = require('../config/database');
const DEFAULTS = {
attempts: 3,
baseDelayMs: 200,
};
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* Führt eine DB-Operation bis zu `attempts` mal aus. Nach einem Fehler:
* kurzes Backoff, dann Verbindung mit authenticate() neu prüfen (frische
* Verbindung aus dem Pool), erneuter Versuch.
* Kein sequelize.close() — würde die gemeinsame Instanz für alle Requests killen.
*/
async function withDbRetries(operation, options = {}) {
const { attempts, baseDelayMs } = { ...DEFAULTS, ...options };
let lastError;
for (let attempt = 1; attempt <= attempts; attempt++) {
try {
if (attempt > 1) {
const backoff = baseDelayMs * 2 ** (attempt - 2);
await delay(backoff);
try {
await sequelize.authenticate();
} catch (authErr) {
console.warn(
`DB authenticate vor Wiederholung ${attempt}/${attempts} fehlgeschlagen:`,
authErr.message
);
}
}
return await operation();
} catch (error) {
lastError = error;
console.error(
`DB-Operation Versuch ${attempt}/${attempts} fehlgeschlagen:`,
error.message
);
if (attempt === attempts) {
throw error;
}
}
}
throw lastError;
}
module.exports = { withDbRetries };