Preparing rollQueue to handle api Rolls

This commit is contained in:
Ean Milligan (Bastion) 2022-06-20 19:18:23 -04:00
parent 170c089fe9
commit a0dae3416f
3 changed files with 49 additions and 31 deletions

View File

@ -11,6 +11,7 @@ import {
import { rollingEmbed, warnColor } from '../commandUtils.ts'; import { rollingEmbed, warnColor } from '../commandUtils.ts';
import rollFuncs from './roll/_index.ts'; import rollFuncs from './roll/_index.ts';
import { queueRoll } from '../solver/rollQueue.ts'; import { queueRoll } from '../solver/rollQueue.ts';
import { QueuedRoll } from '../mod.d.ts';
export const roll = async (message: DiscordenoMessage, args: string[], command: string) => { export const roll = async (message: DiscordenoMessage, args: string[], command: string) => {
// Light telemetry to see how many times a command is being run // Light telemetry to see how many times a command is being run
@ -48,7 +49,14 @@ export const roll = async (message: DiscordenoMessage, args: string[], command:
// Rejoin all of the args and send it into the solver, if solver returns a falsy item, an error object will be substituded in // Rejoin all of the args and send it into the solver, if solver returns a falsy item, an error object will be substituded in
const rollCmd = `${command} ${args.join(' ')}`; const rollCmd = `${command} ${args.join(' ')}`;
queueRoll(m, message, originalCommand, rollCmd, modifiers); queueRoll(
<QueuedRoll> {
apiRoll: false,
dd: { m, message, originalCommand },
rollCmd,
modifiers,
},
);
} catch (e) { } catch (e) {
log(LT.ERROR, `Undandled Error: ${JSON.stringify(e)}`); log(LT.ERROR, `Undandled Error: ${JSON.stringify(e)}`);
} }

8
src/mod.d.ts vendored
View File

@ -26,9 +26,17 @@ export type RollModifiers = {
// QueuedRoll is the structure to track rolls we could not immediately handle // QueuedRoll is the structure to track rolls we could not immediately handle
export type QueuedRoll = { export type QueuedRoll = {
apiRoll: boolean;
api: {
requestEvent: Deno.RequestEvent;
channelId: BigInt;
userId: BigInt;
};
dd: {
m: DiscordenoMessage; m: DiscordenoMessage;
message: DiscordenoMessage; message: DiscordenoMessage;
originalCommand: string; originalCommand: string;
};
rollCmd: string; rollCmd: string;
modifiers: RollModifiers; modifiers: RollModifiers;
}; };

View File

@ -18,11 +18,11 @@ let currentWorkers = 0;
const rollQueue: Array<QueuedRoll> = []; const rollQueue: Array<QueuedRoll> = [];
// Handle setting up and calling the rollWorker // Handle setting up and calling the rollWorker
const handleRollWorker = async (m: DiscordenoMessage, message: DiscordenoMessage, originalCommand: string, rollCmd: string, modifiers: RollModifiers) => { const handleRollWorker = async (rq: QueuedRoll) => {
currentWorkers++; currentWorkers++;
// gmModifiers used to create gmEmbed (basically just turn off the gmRoll) // gmModifiers used to create gmEmbed (basically just turn off the gmRoll)
const gmModifiers = JSON.parse(JSON.stringify(modifiers)); const gmModifiers = JSON.parse(JSON.stringify(rq.modifiers));
gmModifiers.gmRoll = false; gmModifiers.gmRoll = false;
const rollWorker = new Worker(new URL('../solver/rollWorker.ts', import.meta.url).href, { type: 'module' }); const rollWorker = new Worker(new URL('../solver/rollWorker.ts', import.meta.url).href, { type: 'module' });
@ -30,10 +30,10 @@ const handleRollWorker = async (m: DiscordenoMessage, message: DiscordenoMessage
const workerTimeout = setTimeout(async () => { const workerTimeout = setTimeout(async () => {
rollWorker.terminate(); rollWorker.terminate();
currentWorkers--; currentWorkers--;
m.edit({ rq.dd.m.edit({
embeds: [ embeds: [
(await generateRollEmbed( (await generateRollEmbed(
message.authorId, rq.dd.message.authorId,
<SolvedRoll> { <SolvedRoll> {
error: true, error: true,
errorCode: 'TooComplex', errorCode: 'TooComplex',
@ -46,8 +46,8 @@ const handleRollWorker = async (m: DiscordenoMessage, message: DiscordenoMessage
}, config.limits.workerTimeout); }, config.limits.workerTimeout);
rollWorker.postMessage({ rollWorker.postMessage({
rollCmd, rollCmd: rq.rollCmd,
modifiers, modifiers: rq.modifiers,
}); });
rollWorker.addEventListener('message', async (workerMessage) => { rollWorker.addEventListener('message', async (workerMessage) => {
@ -55,49 +55,49 @@ const handleRollWorker = async (m: DiscordenoMessage, message: DiscordenoMessage
currentWorkers--; currentWorkers--;
clearTimeout(workerTimeout); clearTimeout(workerTimeout);
const returnmsg = workerMessage.data; const returnmsg = workerMessage.data;
const pubEmbedDetails = await generateRollEmbed(message.authorId, returnmsg, modifiers); const pubEmbedDetails = await generateRollEmbed(rq.dd.message.authorId, returnmsg, rq.modifiers);
const gmEmbedDetails = await generateRollEmbed(message.authorId, returnmsg, gmModifiers); const gmEmbedDetails = await generateRollEmbed(rq.dd.message.authorId, returnmsg, gmModifiers);
const countEmbed = generateCountDetailsEmbed(returnmsg.counts); const countEmbed = generateCountDetailsEmbed(returnmsg.counts);
// If there was an error, report it to the user in hopes that they can determine what they did wrong // If there was an error, report it to the user in hopes that they can determine what they did wrong
if (returnmsg.error) { if (returnmsg.error) {
m.edit({ embeds: [pubEmbedDetails.embed] }); rq.dd.m.edit({ embeds: [pubEmbedDetails.embed] });
if (DEVMODE && config.logRolls) { if (DEVMODE && config.logRolls) {
// If enabled, log rolls so we can see what went wrong // If enabled, log rolls so we can see what went wrong
dbClient.execute(queries.insertRollLogCmd(0, 1), [originalCommand, returnmsg.errorCode, m.id]).catch((e) => { dbClient.execute(queries.insertRollLogCmd(0, 1), [rq.dd.originalCommand, returnmsg.errorCode, rq.dd.m.id]).catch((e) => {
log(LT.ERROR, `Failed to insert into DB: ${JSON.stringify(e)}`); log(LT.ERROR, `Failed to insert into DB: ${JSON.stringify(e)}`);
}); });
} }
} else { } else {
// Determine if we are to send a GM roll or a normal roll // Determine if we are to send a GM roll or a normal roll
if (modifiers.gmRoll) { if (rq.modifiers.gmRoll) {
// Send the public embed to correct channel // Send the public embed to correct channel
m.edit({ embeds: [pubEmbedDetails.embed] }); rq.dd.m.edit({ embeds: [pubEmbedDetails.embed] });
// And message the full details to each of the GMs, alerting roller of every GM that could not be messaged // And message the full details to each of the GMs, alerting roller of every GM that could not be messaged
modifiers.gms.forEach(async (gm) => { rq.modifiers.gms.forEach(async (gm) => {
log(LT.LOG, `Messaging GM ${gm}`); log(LT.LOG, `Messaging GM ${gm}`);
// Attempt to DM the GM and send a warning if it could not DM a GM // Attempt to DM the GM and send a warning if it could not DM a GM
await sendDirectMessage(BigInt(gm.substring(2, gm.length - 1)), { await sendDirectMessage(BigInt(gm.substring(2, gm.length - 1)), {
embeds: modifiers.count ? [gmEmbedDetails.embed, countEmbed] : [gmEmbedDetails.embed], embeds: rq.modifiers.count ? [gmEmbedDetails.embed, countEmbed] : [gmEmbedDetails.embed],
}).then(async () => { }).then(async () => {
// Check if we need to attach a file and send it after the initial details sent // Check if we need to attach a file and send it after the initial details sent
if (gmEmbedDetails.hasAttachment) { if (gmEmbedDetails.hasAttachment) {
await sendDirectMessage(BigInt(gm.substring(2, gm.length - 1)), { await sendDirectMessage(BigInt(gm.substring(2, gm.length - 1)), {
file: gmEmbedDetails.attachment, file: gmEmbedDetails.attachment,
}).catch(() => { }).catch(() => {
message.reply(generateDMFailed(gm)); rq.dd.message.reply(generateDMFailed(gm));
}); });
} }
}).catch(() => { }).catch(() => {
message.reply(generateDMFailed(gm)); rq.dd.message.reply(generateDMFailed(gm));
}); });
}); });
} else { } else {
// Not a gm roll, so just send normal embed to correct channel // Not a gm roll, so just send normal embed to correct channel
const n = await m.edit({ const n = await rq.dd.m.edit({
embeds: modifiers.count ? [pubEmbedDetails.embed, countEmbed] : [pubEmbedDetails.embed], embeds: rq.modifiers.count ? [pubEmbedDetails.embed, countEmbed] : [pubEmbedDetails.embed],
}); });
if (pubEmbedDetails.hasAttachment) { if (pubEmbedDetails.hasAttachment) {
// Attachment requires you to send a new message // Attachment requires you to send a new message
@ -114,11 +114,13 @@ const handleRollWorker = async (m: DiscordenoMessage, message: DiscordenoMessage
}; };
// Runs the roll or queues it depending on how many workers are currently running // Runs the roll or queues it depending on how many workers are currently running
export const queueRoll = async (m: DiscordenoMessage, message: DiscordenoMessage, originalCommand: string, rollCmd: string, modifiers: RollModifiers) => { export const queueRoll = async (rq: QueuedRoll) => {
if (!rollQueue.length && currentWorkers < config.limits.maxWorkers) { if (rq.apiRoll) {
handleRollWorker(m, message, originalCommand, rollCmd, modifiers); handleRollWorker(rq);
} else if (!rollQueue.length && currentWorkers < config.limits.maxWorkers) {
handleRollWorker(rq);
} else { } else {
m.edit({ rq.dd.m.edit({
embeds: [{ embeds: [{
color: infoColor2, color: infoColor2,
title: `${config.name} currently has its hands full and has queued your roll.`, title: `${config.name} currently has its hands full and has queued your roll.`,
@ -127,9 +129,9 @@ export const queueRoll = async (m: DiscordenoMessage, message: DiscordenoMessage
The results for this roll will replace this message when it is done.`, The results for this roll will replace this message when it is done.`,
}], }],
}).catch((e) => { }).catch((e) => {
log(LT.ERROR, `Failed to send message: ${JSON.stringify(m)} | ${JSON.stringify(e)}`); log(LT.ERROR, `Failed to send message: ${JSON.stringify(rq.dd.m)} | ${JSON.stringify(e)}`);
}); });
rollQueue.push({ m, message, originalCommand, rollCmd, modifiers }); rollQueue.push(rq);
} }
}; };
@ -139,10 +141,10 @@ setInterval(async () => {
if (rollQueue.length && currentWorkers < config.limits.maxWorkers) { if (rollQueue.length && currentWorkers < config.limits.maxWorkers) {
const temp = rollQueue.shift(); const temp = rollQueue.shift();
if (temp) { if (temp) {
temp.m.edit(rollingEmbed).catch((e) => { temp.dd.m.edit(rollingEmbed).catch((e) => {
log(LT.ERROR, `Failed to send message: ${JSON.stringify(temp.m)} | ${JSON.stringify(e)}`); log(LT.ERROR, `Failed to send message: ${JSON.stringify(temp.dd.m)} | ${JSON.stringify(e)}`);
}); });
handleRollWorker(temp.m, temp.message, temp.originalCommand, temp.rollCmd, temp.modifiers); handleRollWorker(temp);
} }
} }
}, 1000); }, 1000);