perf: offload per-import localized patch to worker + cache FurnitureData parse
Per single furni import, patchLocalizedFurniDataEntries ran for every language and did a full 100k-entry JSON.parse + scan + JSON.stringify on the main thread. That CPU spike is now offloaded to the translation worker (init/prepare/finalize reuses the same pure core helpers), so importing never blocks the event loop. The main thread only does async file I/O and the network LibreTranslate calls. Falls back to the same helpers on the main thread if no worker is available. Also cache readFurniData() by file mtime+size so the 100k-entry JSON is parsed once per change instead of on every import/fix/reconcile read (invalidated on write).
This commit is contained in:
1 parent
6ed1b03e24
commit
6ae7c09682
5 files changed
+502
-226
No files matched your search
@@ -199,10 +199,34 @@ export async function withFurniDataLock<T>(fn: () => Promise<T>): Promise<T> {
|
||||
}
|
||||
}
|
||||
|
||||
let cachedFurniData: {
|
||||
path: string;
|
||||
mtimeMs: number;
|
||||
size: number;
|
||||
data: Record<string, unknown>;
|
||||
} | null = null;
|
||||
|
||||
export async function readFurniData(): Promise<Record<string, unknown>> {
|
||||
const target = await getFurnitureDataReadPath();
|
||||
const stat = await fs.stat(target);
|
||||
if (
|
||||
cachedFurniData &&
|
||||
cachedFurniData.path === target &&
|
||||
cachedFurniData.mtimeMs === stat.mtimeMs &&
|
||||
cachedFurniData.size === stat.size
|
||||
) {
|
||||
// File unchanged since last parse: skip the (expensive) full JSON.parse.
|
||||
return cachedFurniData.data;
|
||||
}
|
||||
const raw = await fs.readFile(/*turbopackIgnore: true*/ target, "utf-8");
|
||||
return JSON.parse(raw);
|
||||
const data = JSON.parse(raw) as Record<string, unknown>;
|
||||
cachedFurniData = {
|
||||
path: target,
|
||||
mtimeMs: stat.mtimeMs,
|
||||
size: stat.size,
|
||||
data,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function writeFurniData(
|
||||
@@ -216,6 +240,9 @@ export async function writeFurniData(
|
||||
await fs.writeFile(/*turbopackIgnore: true*/ tmp, payload, "utf-8");
|
||||
await fs.rename(/*turbopackIgnore: true*/ tmp, target);
|
||||
}
|
||||
// The file just changed: force the next read to reparse instead of serving
|
||||
// a possibly-mutated cached object.
|
||||
cachedFurniData = null;
|
||||
}
|
||||
|
||||
export function buildFurniEntry(params: {
|
||||
|
||||
Reference in new issue
Block a user