feat: render threading

This commit is contained in:
TrèsAbhi committed 2023-10-16 20:08:08 -05:00
1 parent 9495ae2336
commit 6fdd4ba833
7 files changed
+73 -5

No files matched your search

+9 -1
View File
@@ -1,6 +1,14 @@
import { build } from 'esbuild';
import { readdir } from 'fs/promises';
const FILES = ['bot', 'index'];
const FILES = [
'bot',
'index',
(await readdir('src/workers')).map(
(file) => `workers/${file.replace('.ts', '')}`,
),
];
await build({
entryPoints: FILES.map((file) => `src/${file}.ts`),
+9
View File
@@ -0,0 +1,9 @@
import jsxToSvg from './jsxToSvg';
import { svgToPngThreaded } from './svgToPngThreaded';
export default async function jsxToPngThreaded(jsx: JSX.Element) {
const svg = await jsxToSvg(jsx);
const png = await svgToPngThreaded(svg);
return png;
}
+42
View File
@@ -0,0 +1,42 @@
import { Worker } from 'worker_threads';
const MAX_WORKERS = 3;
const workers = [...Array(MAX_WORKERS)].map(() => {
const worker = new Worker(`${__dirname}/workers/render.cjs`);
console.log(`🟡 Launching render worker ${worker.threadId}`);
return worker;
});
const queue: {
svg: string;
resolve: (png: Buffer) => void;
}[] = [];
function manageQueue() {
if (queue.length > 0 && workers.length > 0) {
const { svg, resolve } = queue.shift()!;
const worker = workers.shift()!;
function cleanup() {
workers.push(worker);
manageQueue();
}
worker.postMessage(svg);
worker.on('message', (png: Uint8Array) => {
cleanup();
resolve(Buffer.from(png));
});
worker.on('error', (error) => {
cleanup();
throw error;
});
}
}
export function svgToPngThreaded(svg: string) {
return new Promise<Buffer>((resolve) => {
queue.push({ svg, resolve });
manageQueue();
});
}
@@ -6,7 +6,7 @@ import {
InteractionEditReplyOptions,
} from 'discord.js';
import { InteractionReturnable } from '../../events/interactionCreate';
import jsxToPng from '../blitzkrieg/jsxToPng';
import jsxToPngThreaded from '../blitzkrieg/jsxToPngThreaded';
export default async function normalizeInteractionReturnable(
returnable: InteractionReturnable,
@@ -37,7 +37,7 @@ export default async function normalizeInteractionReturnable(
} else if (item === null) {
return;
} else {
const image = await jsxToPng(item);
const image = await jsxToPngThreaded(item);
if (!reply.files) reply.files = [];
reply.files.push(image);
}
+1 -1
View File
@@ -1,5 +1,5 @@
import { Client } from 'discord.js';
export default function ready(client: Client<true>) {
console.log(`🟢 Bot ${client.shard?.ids[0]} launched`);
console.log(`🟢 Launched bot ${client.shard?.ids[0]}`);
}
+1 -1
View File
@@ -2,7 +2,7 @@ import { manager } from './core/discord/manager';
manager.on('shardCreate', (shard) => {
console.log(`🟡 Launching shard ${shard.id}`);
shard.on('ready', () => console.log(`🟢 Shard ${shard.id} launched`));
shard.on('ready', () => console.log(`🟢 Launched shard ${shard.id}`));
});
manager.spawn();
+9
View File
@@ -0,0 +1,9 @@
import { parentPort, threadId } from 'worker_threads';
import svgToPng from '../core/blitzkrieg/svgToPng';
console.log(`🟢 Launched render worker ${threadId}`);
parentPort?.on('message', async (svg: string) => {
const png = svgToPng(svg);
parentPort?.postMessage(png);
});