perf: offload SWF→Nitro conversion to a worker-thread pool
CI / check (push) Successful in 34s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m0s

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:
openhands committed 2026-08-24 19:02:19 +02:00
1 parent 7116f49e2b
commit 8d1b09f151
6 files changed
+240 -14

No files matched your search

+7 -4
View File
@@ -34,8 +34,8 @@ import {
} from "@/lib/services/import/core/download";
import {
type ConversionResult,
convertSwfToNitro,
extractIconFromSwf,
convertSwfToNitroAsync,
extractIconFromSwfAsync,
parseNitroBundle,
} from "@/lib/services/swf-to-nitro";
import type { ImportSingleResult } from "@/types/furni";
@@ -766,7 +766,7 @@ export async function importSingleFurni(params: {
if (!iconOk && (swfOk || existsSync(/*turbopackIgnore: true*/ swfPath))) {
try {
const swfBuf = await fs.readFile(/*turbopackIgnore: true*/ swfPath);
const iconPng = extractIconFromSwf(swfBuf, baseClassname);
const iconPng = await extractIconFromSwfAsync(swfBuf, baseClassname);
if (iconPng) {
await fs.writeFile(/*turbopackIgnore: true*/ iconPath, iconPng);
iconOk = true;
@@ -795,7 +795,10 @@ export async function importSingleFurni(params: {
try {
if (existsSync(/*turbopackIgnore: true*/ swfPath)) {
const swfBuffer = await fs.readFile(/*turbopackIgnore: true*/ swfPath);
conversionResult = convertSwfToNitro(swfBuffer, baseClassname);
conversionResult = await convertSwfToNitroAsync(
swfBuffer,
baseClassname,
);
await fs.writeFile(
/*turbopackIgnore: true*/ nitroPath,
conversionResult.bundle,