perf: prevent import hanging with timeouts and batching
- verifyAndFixInteractionModesCount: paginated DB queries (500/batch) instead of loading all items into memory at once - withFurniDataLock: add 60s chain timeout to prevent deadlocks when a lock holder stalls or crashes - withGamedataLock: same timeout protection for gamedata locks - conversion-pool: add 60s per-job timeout, fall back to main thread - furni/batch: abort signal + post_import progress events + skip post-import steps when client disconnects - furni/batch-regen: abort signal + early exit when disconnected - clone/sync-all: pre-fetch furnidata once per source instead of per item (eliminates 2000+ redundant fetches) - sse-client: add 60s idle timeout to prevent infinite hangs
This commit is contained in:
1 parent
f70d96b81c
commit
7556b1f3fa
5 files changed
+222
-93
No files matched your search
@@ -87,6 +87,8 @@ function pump() {
|
||||
}
|
||||
}
|
||||
|
||||
const CONVERSION_TIMEOUT_MS = 60_000;
|
||||
|
||||
function run(req: Omit<WorkerRequest, "id">): Promise<WorkerResponse> {
|
||||
if (!ensurePool()) {
|
||||
try {
|
||||
@@ -118,6 +120,33 @@ function run(req: Omit<WorkerRequest, "id">): Promise<WorkerResponse> {
|
||||
};
|
||||
queue.push(job);
|
||||
pump();
|
||||
|
||||
// Timeout: if a job takes too long, remove it from the queue
|
||||
// and reject so the caller can fall back to main-thread conversion.
|
||||
const timer = setTimeout(() => {
|
||||
const idx = queue.findIndex((j) => j.req.id === job.req.id);
|
||||
if (idx !== -1) {
|
||||
queue.splice(idx, 1);
|
||||
pending.delete(job.req.id);
|
||||
reject(new Error("Conversion timed out"));
|
||||
} else {
|
||||
// Already dispatched to a worker — the worker is
|
||||
// responsible for timing out its own task.
|
||||
reject(new Error("Conversion timed out"));
|
||||
}
|
||||
}, CONVERSION_TIMEOUT_MS);
|
||||
|
||||
// Clear the timer once the job resolves/rejects
|
||||
const origResolve = resolve;
|
||||
const origReject = reject;
|
||||
job.resolve = (r) => {
|
||||
clearTimeout(timer);
|
||||
origResolve(r);
|
||||
};
|
||||
job.reject = (e) => {
|
||||
clearTimeout(timer);
|
||||
origReject(e);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user