perf: offload SWF→Nitro conversion to a worker-thread pool
The synchronous convertSwfToNitro / extractIconFromSwf calls (pure CPU, no DB/network) now run in a small worker pool so the main Node event loop stays free during imports — the dominant import-time CPU spike is moved off the request thread. The pool degrades gracefully to a synchronous fallback if workers can't be created, and is skipped in the test environment.
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import { parentPort } from "node:worker_threads";
|
||||
import { convertSwfToNitro, extractIconFromSwf } from "./index";
|
||||
|
||||
export interface ConvertRequest {
|
||||
id: number;
|
||||
type: "convert";
|
||||
buffer: Buffer;
|
||||
classname: string;
|
||||
}
|
||||
|
||||
export interface IconRequest {
|
||||
id: number;
|
||||
type: "icon";
|
||||
buffer: Buffer;
|
||||
classname: string;
|
||||
}
|
||||
|
||||
export type WorkerRequest = ConvertRequest | IconRequest;
|
||||
|
||||
export type WorkerResponse =
|
||||
| {
|
||||
id: number;
|
||||
ok: true;
|
||||
result?: import("./index").ConversionResult;
|
||||
icon?: Buffer | null;
|
||||
}
|
||||
| { id: number; ok: false; error: string };
|
||||
|
||||
if (parentPort) {
|
||||
parentPort.on("message", (msg: WorkerRequest) => {
|
||||
try {
|
||||
if (msg.type === "convert") {
|
||||
const result = convertSwfToNitro(msg.buffer, msg.classname);
|
||||
parentPort!.postMessage({
|
||||
id: msg.id,
|
||||
ok: true,
|
||||
result,
|
||||
} satisfies WorkerResponse);
|
||||
} else {
|
||||
const icon = extractIconFromSwf(msg.buffer, msg.classname);
|
||||
parentPort!.postMessage({
|
||||
id: msg.id,
|
||||
ok: true,
|
||||
icon: icon ?? null,
|
||||
} satisfies WorkerResponse);
|
||||
}
|
||||
} catch (err) {
|
||||
parentPort!.postMessage({
|
||||
id: msg.id,
|
||||
ok: false,
|
||||
error: (err as Error).message,
|
||||
} satisfies WorkerResponse);
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user