Skip to content

Commit 6075dd2

Browse files
committed
fix(worker): Ensure worker promises are reused
When running task in a worker in "parallel" the access to the worker must be performed through the same worker promise otherwise requests and responses can get interleaved. This situation can occur if for example Promise.all(...) is used to run the tasks in a worker. To prevent this issue we attach the work promise to the worker, so it can be used again if the worker is reused.
1 parent c33faa1 commit 6075dd2

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

src/core/internal/createWebWorkerPromise.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,24 @@ interface createWebWorkerPromiseResult {
88
worker: Worker
99
}
1010

11+
interface itkWorker extends Worker {
12+
workerPromise?: typeof WebworkerPromise
13+
}
14+
1115
// Internal function to create a web worker promise
1216
async function createWebWorkerPromise (existingWorker: Worker | null): Promise<createWebWorkerPromiseResult> {
17+
let workerPromise: typeof WebworkerPromise
1318
if (existingWorker != null) {
14-
const webworkerPromise = new WebworkerPromise(existingWorker)
15-
return await Promise.resolve({ webworkerPromise, worker: existingWorker })
19+
// See if we have a worker promise attached the worker, if so reuse it. This ensures
20+
// that we can safely reuse the worker without issues.
21+
const itkWebWorker = existingWorker as itkWorker;
22+
if (itkWebWorker.workerPromise !== undefined) {
23+
workerPromise = itkWebWorker.workerPromise;
24+
} else {
25+
workerPromise = new WebworkerPromise(existingWorker);
26+
}
27+
28+
return await Promise.resolve({ webworkerPromise: workerPromise, worker: existingWorker })
1629
}
1730

1831
let worker = null
@@ -49,8 +62,13 @@ async function createWebWorkerPromise (existingWorker: Worker | null): Promise<c
4962
}
5063
}
5164

52-
const webworkerPromise = new WebworkerPromise(worker)
53-
return { webworkerPromise, worker }
65+
const webworkerPromise = new WebworkerPromise(worker);
66+
67+
// Attach the worker promise to the worker, so if the worker is reused we can
68+
// also reuse the the worker promise.
69+
const itkWebWorker = (worker as itkWorker);
70+
itkWebWorker.workerPromise = webworkerPromise;
71+
return { webworkerPromise, worker: itkWebWorker }
5472
}
5573

5674
export default createWebWorkerPromise

0 commit comments

Comments
 (0)