52 lines
1.4 KiB
JavaScript
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 };
|