Merge branch 'devel'
This commit is contained in:
commit
dc01b994e7
|
@ -180,9 +180,19 @@ class User {
|
||||||
}
|
}
|
||||||
|
|
||||||
incrementPixelcount(amount = 1) {
|
incrementPixelcount(amount = 1) {
|
||||||
if (this.regUser) {
|
if (!this.id) {
|
||||||
incrementPixelcount(this.regUser, amount);
|
return;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* incrementation gets queued to be processed
|
||||||
|
* in batches
|
||||||
|
*/
|
||||||
|
if (!this.queuedPxlIncrement) {
|
||||||
|
this.queuedPxlIncrement = amount;
|
||||||
|
incrementPixelcount(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.queuedPxlIncrement += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTotalPixels() {
|
async getTotalPixels() {
|
||||||
|
|
|
@ -205,44 +205,75 @@ export async function getNamesToIds(ids) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* increment user pixelcount in a batched transaction
|
* increment user pixelcount in batches sequentially
|
||||||
|
* Queue directly accesses queuedPxlIncrement in user object
|
||||||
*/
|
*/
|
||||||
const incrementQueue = [];
|
const incrementQueue = [];
|
||||||
let pushLoop = null;
|
let pushLoop = null;
|
||||||
|
let lastLog = 0;
|
||||||
const incrementLoop = async () => {
|
const incrementLoop = async () => {
|
||||||
if (!incrementQueue.length) {
|
if (!incrementQueue.length) {
|
||||||
pushLoop = null;
|
pushLoop = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await sequelize.transaction(async (t) => {
|
incrementQueue.sort((a, b) => {
|
||||||
while (incrementQueue.length) {
|
const aa = a.queuedPxlIncrement;
|
||||||
const [model, amount] = incrementQueue.pop();
|
const ba = b.queuedPxlIncrement;
|
||||||
// eslint-disable-next-line no-await-in-loop
|
if (aa < ba) return -1;
|
||||||
await model.increment(
|
if (aa > ba) return 1;
|
||||||
['totalPixels', 'dailyTotalPixels'],
|
return 0;
|
||||||
{ by: amount, transaction: t },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
|
let cnt = incrementQueue.length;
|
||||||
|
let user = incrementQueue.pop();
|
||||||
|
while (cnt) {
|
||||||
|
cnt -= 1;
|
||||||
|
const amount = user.queuedPxlIncrement;
|
||||||
|
user.queuedPxlIncrement = 0;
|
||||||
|
const ids = [user.id];
|
||||||
|
while (cnt) {
|
||||||
|
cnt -= 1;
|
||||||
|
user = incrementQueue.pop();
|
||||||
|
if (user.queuedPxlIncrement !== amount) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
user.queuedPxlIncrement = 0;
|
||||||
|
ids.push(user.id);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
await RegUser.increment(['totalPixels', 'dailyTotalPixels'], {
|
||||||
|
by: amount,
|
||||||
|
where: {
|
||||||
|
id: ids,
|
||||||
|
},
|
||||||
|
silent: true,
|
||||||
|
raw: true,
|
||||||
|
// TODO: remove this after testing
|
||||||
|
logging: (msg) => {
|
||||||
|
const now = Date.now();
|
||||||
|
if (now - 5000 > lastLog) {
|
||||||
|
lastLog = now;
|
||||||
|
logger.warn(msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.warn(`Error on batched incrementing pixelcounts: ${err.message}`);
|
logger.warn(`Error on pixel increment: ${err.message}`);
|
||||||
|
incrementQueue.forEach((q) => {
|
||||||
|
if (q) q.queuedPxlIncrement = 0;
|
||||||
|
});
|
||||||
|
incrementQueue.length = 0;
|
||||||
}
|
}
|
||||||
pushLoop = setTimeout(incrementLoop, 50);
|
pushLoop = setTimeout(incrementLoop, 250);
|
||||||
};
|
};
|
||||||
// TODO remove this after testing
|
// TODO remove this after testing
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log('INCREMENTATION QUEUE SIZE', incrementQueue.length, pushLoop);
|
console.log('INCREMENTATION QUEUE SIZE', incrementQueue.length, pushLoop);
|
||||||
}, 300000);
|
}, 300000);
|
||||||
export async function incrementPixelcount(model, amount) {
|
export async function incrementPixelcount(user) {
|
||||||
const exists = incrementQueue.find((q) => q[0] === model);
|
incrementQueue.push(user);
|
||||||
if (exists) {
|
|
||||||
exists[1] += amount;
|
|
||||||
} else {
|
|
||||||
incrementQueue.push([model, amount]);
|
|
||||||
}
|
|
||||||
if (!pushLoop) {
|
if (!pushLoop) {
|
||||||
pushLoop = setTimeout(incrementLoop, 0);
|
pushLoop = setTimeout(incrementLoop, 0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user