not sure how this did not come up with the api in the past, but found out a resolve func cannot be passed into a worker. devised a system to store these off while the worker works and pick them back up on the main thread when applicable

This commit is contained in:
Ean Milligan 2025-07-13 04:25:55 -04:00
parent fe70166e6a
commit f19c4216c0
7 changed files with 77 additions and 49 deletions

View File

@ -9,6 +9,7 @@ import { RollModifiers } from 'artigen/dice/dice.d.ts';
import { removeWorker } from 'artigen/managers/countManager.ts';
import { QueuedRoll } from 'artigen/managers/manager.d.ts';
import { ApiResolveMap, TestResolveMap } from 'artigen/managers/resolveManager.ts';
import { generateCountDetailsEmbed, generateDMFailed, generateRollDistsEmbed, generateRollEmbed } from 'artigen/utils/embeds.ts';
import { loggingEnabled } from 'artigen/utils/logFlag.ts';
@ -29,6 +30,11 @@ const getUserIdForEmbed = (rollRequest: QueuedRoll): bigint => {
};
export const onWorkerComplete = async (workerMessage: MessageEvent<SolvedRoll>, workerTimeout: number, rollRequest: QueuedRoll) => {
const apiResolve = rollRequest.apiRoll ? ApiResolveMap.get(rollRequest.resolve as string) : undefined;
const testResolve = rollRequest.testRoll ? TestResolveMap.get(rollRequest.resolve as string) : undefined;
rollRequest.apiRoll && ApiResolveMap.delete(rollRequest.resolve as string);
rollRequest.testRoll && TestResolveMap.delete(rollRequest.resolve as string);
let apiErroredOut = false;
try {
removeWorker();
@ -81,15 +87,16 @@ export const onWorkerComplete = async (workerMessage: MessageEvent<SolvedRoll>,
// If there was an error, report it to the user in hopes that they can determine what they did wrong
if (returnMsg.error) {
if (rollRequest.apiRoll) {
rollRequest.api.resolve(stdResp.InternalServerError(returnMsg.errorMsg));
apiResolve && apiResolve(stdResp.InternalServerError(returnMsg.errorMsg));
} else if (rollRequest.ddRoll) {
rollRequest.dd.myResponse.edit({ embeds: pubEmbeds });
} else if (rollRequest.testRoll) {
rollRequest.test.resolve({
error: true,
errorMsg: returnMsg.errorMsg,
errorCode: returnMsg.errorCode,
});
testResolve &&
testResolve({
error: true,
errorMsg: returnMsg.errorMsg,
errorCode: returnMsg.errorCode,
});
}
if (rollRequest.apiRoll) {
@ -104,9 +111,10 @@ export const onWorkerComplete = async (workerMessage: MessageEvent<SolvedRoll>,
// Test roll will assume that messages send successfully
if (rollRequest.testRoll) {
rollRequest.test.resolve({
error: false,
});
testResolve &&
testResolve({
error: false,
});
return;
}
@ -119,7 +127,7 @@ export const onWorkerComplete = async (workerMessage: MessageEvent<SolvedRoll>,
embeds: pubEmbeds,
}).catch(() => {
apiErroredOut = true;
rollRequest.api.resolve(stdResp.InternalServerError('Message failed to send - location 0.'));
apiResolve && apiResolve(stdResp.InternalServerError('Message failed to send - location 0.'));
});
} else {
// Send the public embed to correct channel
@ -167,7 +175,7 @@ export const onWorkerComplete = async (workerMessage: MessageEvent<SolvedRoll>,
embeds: pubEmbeds,
}).catch(() => {
apiErroredOut = true;
rollRequest.api.resolve(stdResp.InternalServerError('Message failed to send - location 1.'));
apiResolve && apiResolve(stdResp.InternalServerError('Message failed to send - location 1.'));
});
} else {
newMsg = await rollRequest.dd.myResponse.edit({
@ -207,20 +215,21 @@ export const onWorkerComplete = async (workerMessage: MessageEvent<SolvedRoll>,
.execute(queries.insertRollLogCmd(1, 0), [rollRequest.originalCommand, returnMsg.errorCode, newMsg ? newMsg.id : null])
.catch((e) => utils.commonLoggers.dbError('rollQueue.ts:155', 'insert into', e));
rollRequest.api.resolve(
stdResp.OK(
JSON.stringify(
rollRequest.modifiers.count
? {
counts: returnMsg.counts,
details: pubEmbedDetails,
}
: {
details: pubEmbedDetails,
},
),
),
);
apiResolve &&
apiResolve(
stdResp.OK(
JSON.stringify(
rollRequest.modifiers.count
? {
counts: returnMsg.counts,
details: pubEmbedDetails,
}
: {
details: pubEmbedDetails,
}
)
)
);
}
} catch (e) {
log(LT.ERROR, `Unhandled rollRequest Error: ${JSON.stringify(e)}`);
@ -230,25 +239,25 @@ export const onWorkerComplete = async (workerMessage: MessageEvent<SolvedRoll>,
(
await generateRollEmbed(
rollRequest.dd.originalMessage.authorId,
<SolvedRoll> {
<SolvedRoll>{
error: true,
errorMsg:
`Something weird went wrong, likely the requested roll is too complex and caused the response to be too large for Discord. Try breaking the request down into smaller messages and try again.\n\nIf this error continues to come up, please \`${config.prefix}report\` this to my developer.`,
errorMsg: `Something weird went wrong, likely the requested roll is too complex and caused the response to be too large for Discord. Try breaking the request down into smaller messages and try again.\n\nIf this error continues to come up, please \`${config.prefix}report\` this to my developer.`,
errorCode: 'UnhandledWorkerComplete',
},
<RollModifiers> {},
<RollModifiers>{}
)
).embed,
],
});
} else if (rollRequest.apiRoll && !apiErroredOut) {
rollRequest.api.resolve(stdResp.InternalServerError(JSON.stringify(e)));
apiResolve && apiResolve(stdResp.InternalServerError(JSON.stringify(e)));
} else if (rollRequest.testRoll) {
rollRequest.test.resolve({
error: true,
errorMsg: 'Something weird went wrong.',
errorCode: 'UnhandledWorkerComplete',
});
testResolve &&
testResolve({
error: true,
errorMsg: 'Something weird went wrong.',
errorCode: 'UnhandledWorkerComplete',
});
}
}
};

View File

@ -1,10 +1,18 @@
import { log, LogTypes as LT } from '@Log4Deno';
import { nanoid } from '@nanoid';
import { QueuedRoll } from 'artigen/managers/manager.d.ts';
import { ApiResolveMap, TestResolveMap } from 'artigen/managers/resolveManager.ts';
import { loggingEnabled } from 'artigen/utils/logFlag.ts';
export const onWorkerReady = (rollWorker: Worker, rollRequest: QueuedRoll) => {
if ((rollRequest.apiRoll || rollRequest.testRoll) && typeof rollRequest.resolve !== 'string') {
const resolveId = nanoid();
rollRequest.apiRoll && ApiResolveMap.set(resolveId, rollRequest.resolve);
rollRequest.testRoll && TestResolveMap.set(resolveId, rollRequest.resolve);
rollRequest.resolve = resolveId;
}
loggingEnabled && log(LT.LOG, `Sending roll to worker: ${rollRequest.rollCmd}, ${JSON.stringify(rollRequest.modifiers)}`);
rollWorker.postMessage(rollRequest);
};

View File

@ -4,6 +4,7 @@ import { RollModifiers } from 'artigen/dice/dice.d.ts';
import { removeWorker } from 'artigen/managers/countManager.ts';
import { QueuedRoll } from 'artigen/managers/manager.d.ts';
import { ApiResolveMap, TestResolveMap } from 'artigen/managers/resolveManager.ts';
import { generateRollEmbed } from 'artigen/utils/embeds.ts';
@ -14,9 +15,13 @@ import utils from 'utils/utils.ts';
export const terminateWorker = async (rollWorker: Worker, rollRequest: QueuedRoll) => {
rollWorker.terminate();
removeWorker();
const apiResolve = rollRequest.apiRoll ? ApiResolveMap.get(rollRequest.resolve as string) : undefined;
const testResolve = rollRequest.testRoll ? TestResolveMap.get(rollRequest.resolve as string) : undefined;
rollRequest.apiRoll && ApiResolveMap.delete(rollRequest.resolve as string);
rollRequest.testRoll && TestResolveMap.delete(rollRequest.resolve as string);
if (rollRequest.apiRoll) {
rollRequest.api.resolve(stdResp.RequestTimeout('Roll took too long to process, try breaking roll down into simpler parts'));
apiResolve && apiResolve(stdResp.RequestTimeout('Roll took too long to process, try breaking roll down into simpler parts'));
} else if (rollRequest.ddRoll) {
rollRequest.dd.myResponse
.edit({
@ -24,22 +29,23 @@ export const terminateWorker = async (rollWorker: Worker, rollRequest: QueuedRol
(
await generateRollEmbed(
rollRequest.dd.originalMessage.authorId,
<SolvedRoll> {
<SolvedRoll>{
error: true,
errorCode: 'TooComplex',
errorMsg: 'Error: Roll took too long to process, try breaking roll down into simpler parts',
},
<RollModifiers> {},
<RollModifiers>{}
)
).embed,
],
})
.catch((e) => utils.commonLoggers.messageEditError('rollQueue.ts:51', rollRequest.dd.myResponse, e));
} else if (rollRequest.testRoll) {
rollRequest.test.resolve({
error: true,
errorCode: 'TooComplex',
errorMsg: 'Error: Roll took too long to process, try breaking roll down into simpler parts',
});
testResolve &&
testResolve({
error: true,
errorCode: 'TooComplex',
errorMsg: 'Error: Roll took too long to process, try breaking roll down into simpler parts',
});
}
};

View File

@ -8,12 +8,13 @@ interface BaseQueuedRoll {
modifiers: RollModifiers;
originalCommand: string;
}
export type ApiResolve = (value: Response | PromiseLike<Response>) => void;
interface ApiQueuedRoll extends BaseQueuedRoll {
apiRoll: true;
ddRoll: false;
testRoll: false;
resolve: string | ApiResolve;
api: {
resolve: (value: Response | PromiseLike<Response>) => void;
channelId: bigint;
userId: bigint;
};
@ -36,12 +37,11 @@ interface TestResultSuccess {
error: false;
}
export type TestResults = TestResultFail | TestResultSuccess;
export type TestResolve = (value: TestResults) => void;
interface TestQueuedRoll extends BaseQueuedRoll {
apiRoll: false;
ddRoll: false;
testRoll: true;
test: {
resolve: (value: TestResults) => void;
};
resolve: string | TestResolve;
}
export type QueuedRoll = ApiQueuedRoll | DDQueuedRoll | TestQueuedRoll;

View File

@ -0,0 +1,4 @@
import { ApiResolve, TestResolve } from 'artigen/managers/manager.d.ts';
export const ApiResolveMap = new Map<string, ApiResolve>();
export const TestResolveMap = new Map<string, TestResolve>();

View File

@ -264,7 +264,7 @@ If you are trying to update an existing alias, but forgot the name, please run t
apiRoll: false,
ddRoll: false,
testRoll: true,
test: { resolve },
resolve,
rollCmd,
modifiers,
originalCommand: rawRollStr,

View File

@ -164,7 +164,8 @@ export const apiRoll = async (query: Map<string, string>, apiUserid: bigint): Pr
apiRoll: true,
ddRoll: false,
testRoll: false,
api: { resolve, channelId: BigInt(query.get('channel') || '0'), userId: BigInt(query.get('user') || '') },
resolve,
api: { channelId: BigInt(query.get('channel') || '0'), userId: BigInt(query.get('user') || '') },
rollCmd,
modifiers,
originalCommand,