const leaderboards = require("../Data/leaderboard"); const BATCH_SIZE = 1000; const INTERVAL_TIME = 60000; async function leaderboardLoop() { for (let i = 0, length = leaderboards.length; i < length; i++) { const leaderboard = leaderboards[i]; const databaseName = `leaderboard_${i + 1}`; const queries = []; const entries = []; const dbConnection = await db.getConnection(); await dbConnection.beginTransaction(); leaderboard.list.clearEach((key, value) => entries.push([key, value])); for (let j = 0, length = Math.ceil(entries.length / BATCH_SIZE); j < length; j++) { const batch = entries.slice(j * BATCH_SIZE, (j + 1) * BATCH_SIZE); let leaderboardFromDB = null; if (i === 0) leaderboardFromDB = dbConnection.query(`INSERT INTO ${databaseName} (id, amount) VALUES ? ON DUPLICATE KEY UPDATE amount = VALUES(amount)`, [batch]); else leaderboardFromDB = dbConnection.query(`INSERT INTO ${databaseName} (id, amount) VALUES ? ON DUPLICATE KEY UPDATE amount = amount + VALUES(amount)`, [batch]); queries.push(leaderboardFromDB); }; try { await Promise.all(queries); await dbConnection.commit(); } catch { await dbConnection.rollback(); } finally { dbConnection.release(); }; const leaderboardSizeFromDB = await execute(`SELECT COUNT(*) AS size FROM ${databaseName}`); leaderboard.size = leaderboardSizeFromDB.data ? leaderboardSizeFromDB.data[0].size : 0; leaderboard.cache = {}; }; }; setInterval(leaderboardLoop, INTERVAL_TIME); module.exports = leaderboardLoop; /* Periodically saves leaderboard changes to disk in batches */