Skip to content

Commit 84da25b

Browse files
committed
refactor: make worker initialization lazy in workerPool
Defer worker thread creation until first use. Previously the worker was initialized at module load time, causing unnecessary overhead. Now createWorker() is called lazily from run(), reducing startup cost.
1 parent 80ef4f2 commit 84da25b

File tree

1 file changed

+44
-35
lines changed

1 file changed

+44
-35
lines changed

src/utils/main/workerPool.ts

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -32,48 +32,53 @@ const pendingPromises = new Map<
3232
// This is safe because the heavy ai-tokenizer imports happen in the worker thread, not the main thread
3333
const requireForResolve = createRequire(__filename);
3434
const workerPath = requireForResolve.resolve("./tokenizer.worker");
35-
const worker = new Worker(workerPath);
35+
let worker: Worker | null = null;
36+
function createWorker(): Worker {
37+
const worker = new Worker(workerPath);
3638

37-
// Handle messages from worker
38-
worker.on("message", (response: WorkerResponse) => {
39-
const pending = pendingPromises.get(response.messageId);
40-
if (!pending) {
41-
console.error(`[workerPool] No pending promise for messageId ${response.messageId}`);
42-
return;
43-
}
39+
// Handle messages from worker
40+
worker.on("message", (response: WorkerResponse) => {
41+
const pending = pendingPromises.get(response.messageId);
42+
if (!pending) {
43+
console.error(`[workerPool] No pending promise for messageId ${response.messageId}`);
44+
return;
45+
}
4446

45-
pendingPromises.delete(response.messageId);
47+
pendingPromises.delete(response.messageId);
4648

47-
if ("error" in response) {
48-
const error = new Error(response.error.message);
49-
error.stack = response.error.stack;
50-
pending.reject(error);
51-
} else {
52-
pending.resolve(response.result);
53-
}
54-
});
55-
56-
// Handle worker errors
57-
worker.on("error", (error) => {
58-
console.error("[workerPool] Worker error:", error);
59-
// Reject all pending promises
60-
for (const pending of pendingPromises.values()) {
61-
pending.reject(error);
62-
}
63-
pendingPromises.clear();
64-
});
49+
if ("error" in response) {
50+
const error = new Error(response.error.message);
51+
error.stack = response.error.stack;
52+
pending.reject(error);
53+
} else {
54+
pending.resolve(response.result);
55+
}
56+
});
6557

66-
// Handle worker exit
67-
worker.on("exit", (code) => {
68-
if (code !== 0) {
69-
console.error(`[workerPool] Worker stopped with exit code ${code}`);
70-
const error = new Error(`Worker stopped with exit code ${code}`);
58+
// Handle worker errors
59+
worker.on("error", (error) => {
60+
console.error("[workerPool] Worker error:", error);
61+
// Reject all pending promises
7162
for (const pending of pendingPromises.values()) {
7263
pending.reject(error);
7364
}
7465
pendingPromises.clear();
75-
}
76-
});
66+
});
67+
68+
// Handle worker exit
69+
worker.on("exit", (code) => {
70+
if (code !== 0) {
71+
console.error(`[workerPool] Worker stopped with exit code ${code}`);
72+
const error = new Error(`Worker stopped with exit code ${code}`);
73+
for (const pending of pendingPromises.values()) {
74+
pending.reject(error);
75+
}
76+
pendingPromises.clear();
77+
}
78+
});
79+
80+
return worker;
81+
}
7782

7883
/**
7984
* Run a task on the worker thread
@@ -82,6 +87,10 @@ worker.on("exit", (code) => {
8287
* @returns A promise that resolves with the task result
8388
*/
8489
export function run<T>(taskName: string, data: unknown): Promise<T> {
90+
if (worker === null) {
91+
worker = createWorker();
92+
}
93+
8594
const messageId = messageIdCounter++;
8695
const request: WorkerRequest = { messageId, taskName, data };
8796

@@ -90,6 +99,6 @@ export function run<T>(taskName: string, data: unknown): Promise<T> {
9099
resolve: resolve as (value: unknown) => void,
91100
reject,
92101
});
93-
worker.postMessage(request);
102+
worker!.postMessage(request);
94103
});
95104
}

0 commit comments

Comments
 (0)