Skip to content

Commit

Permalink
fix(worker): Ensure worker promises are reused
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
cjh1 committed Aug 15, 2022
1 parent c33faa1 commit 6075dd2
Showing 1 changed file with 22 additions and 4 deletions.
26 changes: 22 additions & 4 deletions src/core/internal/createWebWorkerPromise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<createWebWorkerPromiseResult> {
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
Expand Down Expand Up @@ -49,8 +62,13 @@ async function createWebWorkerPromise (existingWorker: Worker | null): Promise<c
}
}

const webworkerPromise = new WebworkerPromise(worker)
return { webworkerPromise, worker }
const webworkerPromise = new WebworkerPromise(worker);

// Attach the worker promise to the worker, so if the worker is reused we can
// also reuse the the worker promise.
const itkWebWorker = (worker as itkWorker);
itkWebWorker.workerPromise = webworkerPromise;
return { webworkerPromise, worker: itkWebWorker }
}

export default createWebWorkerPromise

0 comments on commit 6075dd2

Please sign in to comment.