From 6075dd2993fe82b74bd47276aa0dc2644734c2f7 Mon Sep 17 00:00:00 2001 From: Chris Harris Date: Mon, 15 Aug 2022 15:14:37 -0400 Subject: [PATCH] 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. --- src/core/internal/createWebWorkerPromise.ts | 26 +++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/core/internal/createWebWorkerPromise.ts b/src/core/internal/createWebWorkerPromise.ts index ac943817b..b7129df07 100644 --- a/src/core/internal/createWebWorkerPromise.ts +++ b/src/core/internal/createWebWorkerPromise.ts @@ -8,11 +8,24 @@ interface createWebWorkerPromiseResult { worker: Worker } +interface itkWorker extends Worker { + workerPromise?: typeof WebworkerPromise +} + // Internal function to create a web worker promise async function createWebWorkerPromise (existingWorker: Worker | null): Promise { + let workerPromise: typeof WebworkerPromise if (existingWorker != null) { - const webworkerPromise = new WebworkerPromise(existingWorker) - return await Promise.resolve({ webworkerPromise, worker: existingWorker }) + // See if we have a worker promise attached the worker, if so reuse it. This ensures + // that we can safely reuse the worker without issues. + const itkWebWorker = existingWorker as itkWorker; + if (itkWebWorker.workerPromise !== undefined) { + workerPromise = itkWebWorker.workerPromise; + } else { + workerPromise = new WebworkerPromise(existingWorker); + } + + return await Promise.resolve({ webworkerPromise: workerPromise, worker: existingWorker }) } let worker = null @@ -49,8 +62,13 @@ async function createWebWorkerPromise (existingWorker: Worker | null): Promise