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 rollFuncs from './roll/_index.ts';
import { queueRoll } from '../solver/rollQueue.ts';
import { QueuedRoll } from '../mod.d.ts';
export const roll = async (message: DiscordenoMessage, args: string[], command: string) => {
// 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
const rollCmd = `${command} ${args.join(' ')}`;
queueRoll(m, message, originalCommand, rollCmd, modifiers);
queueRoll(
<QueuedRoll> {
apiRoll: false,
dd: { m, message, originalCommand },
rollCmd,
modifiers,
},
);
} catch (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
export type QueuedRoll = {
apiRoll: boolean;
api: {
requestEvent: Deno.RequestEvent;
channelId: BigInt;
userId: BigInt;
};
dd: {
m: DiscordenoMessage;
message: DiscordenoMessage;
originalCommand: string;
};
rollCmd: string;
modifiers: RollModifiers;
};

View File

@ -18,11 +18,11 @@ let currentWorkers = 0;
const rollQueue: Array<QueuedRoll> = [];
// 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++;
// 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;
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 () => {
rollWorker.terminate();
currentWorkers--;
m.edit({
rq.dd.m.edit({
embeds: [
(await generateRollEmbed(
message.authorId,
rq.dd.message.authorId,
<SolvedRoll> {
error: true,
errorCode: 'TooComplex',
@ -46,8 +46,8 @@ const handleRollWorker = async (m: DiscordenoMessage, message: DiscordenoMessage
}, config.limits.workerTimeout);
rollWorker.postMessage({
rollCmd,
modifiers,
rollCmd: rq.rollCmd,
modifiers: rq.modifiers,
});
rollWorker.addEventListener('message', async (workerMessage) => {
@ -55,49 +55,49 @@ const handleRollWorker = async (m: DiscordenoMessage, message: DiscordenoMessage
currentWorkers--;
clearTimeout(workerTimeout);
const returnmsg = workerMessage.data;
const pubEmbedDetails = await generateRollEmbed(message.authorId, returnmsg, modifiers);
const gmEmbedDetails = await generateRollEmbed(message.authorId, returnmsg, gmModifiers);
const pubEmbedDetails = await generateRollEmbed(rq.dd.message.authorId, returnmsg, rq.modifiers);
const gmEmbedDetails = await generateRollEmbed(rq.dd.message.authorId, returnmsg, gmModifiers);
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 (returnmsg.error) {
m.edit({ embeds: [pubEmbedDetails.embed] });
rq.dd.m.edit({ embeds: [pubEmbedDetails.embed] });
if (DEVMODE && config.logRolls) {
// 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)}`);
});
}
} else {
// 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
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
modifiers.gms.forEach(async (gm) => {
rq.modifiers.gms.forEach(async (gm) => {
log(LT.LOG, `Messaging GM ${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)), {
embeds: modifiers.count ? [gmEmbedDetails.embed, countEmbed] : [gmEmbedDetails.embed],
embeds: rq.modifiers.count ? [gmEmbedDetails.embed, countEmbed] : [gmEmbedDetails.embed],
}).then(async () => {
// Check if we need to attach a file and send it after the initial details sent
if (gmEmbedDetails.hasAttachment) {
await sendDirectMessage(BigInt(gm.substring(2, gm.length - 1)), {
file: gmEmbedDetails.attachment,
}).catch(() => {
message.reply(generateDMFailed(gm));
rq.dd.message.reply(generateDMFailed(gm));
});
}
}).catch(() => {
message.reply(generateDMFailed(gm));
rq.dd.message.reply(generateDMFailed(gm));
});
});
} else {
// Not a gm roll, so just send normal embed to correct channel
const n = await m.edit({
embeds: modifiers.count ? [pubEmbedDetails.embed, countEmbed] : [pubEmbedDetails.embed],
const n = await rq.dd.m.edit({
embeds: rq.modifiers.count ? [pubEmbedDetails.embed, countEmbed] : [pubEmbedDetails.embed],
});
if (pubEmbedDetails.hasAttachment) {
// 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
export const queueRoll = async (m: DiscordenoMessage, message: DiscordenoMessage, originalCommand: string, rollCmd: string, modifiers: RollModifiers) => {
if (!rollQueue.length && currentWorkers < config.limits.maxWorkers) {
handleRollWorker(m, message, originalCommand, rollCmd, modifiers);
export const queueRoll = async (rq: QueuedRoll) => {
if (rq.apiRoll) {
handleRollWorker(rq);
} else if (!rollQueue.length && currentWorkers < config.limits.maxWorkers) {
handleRollWorker(rq);
} else {
m.edit({
rq.dd.m.edit({
embeds: [{
color: infoColor2,
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.`,
}],
}).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) {
const temp = rollQueue.shift();
if (temp) {
temp.m.edit(rollingEmbed).catch((e) => {
log(LT.ERROR, `Failed to send message: ${JSON.stringify(temp.m)} | ${JSON.stringify(e)}`);
temp.dd.m.edit(rollingEmbed).catch((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);