Worker pools
Spread calls across several native Workers with one option, and control when they are created and released.
One option
One Worker runs one task at a time. Set maxWorkers and the same object spreads the calls across several native
Workers.
import { createWorker } from 'easy-web-worker/createWorker';
import workerUrl from '../getting-started/math.worker?worker&url';
import type { MathWorker } from '../getting-started/math.worker';
const math = createWorker<MathWorker>(workerUrl, {
maxWorkers: 4,
workerOptions: { type: 'module' },
});
export function computeAll() {
// three calls, three threads, at the same time
return Promise.all([math.fibonacci(40), math.fibonacci(41), math.fibonacci(42)]);
}The calling code does not change. It does not know whether one Worker or four are behind it.
When Workers are created
With maxWorkers above 1, Workers are created as concurrent calls arrive, so an idle application pays for
none of them. Two options change that:
import { createWorker } from 'easy-web-worker/createWorker';
import workerUrl from '../getting-started/math.worker?worker&url';
import type { MathWorker } from '../getting-started/math.worker';
// create the whole pool up front, for the fastest first call
export const warm = () =>
createWorker<MathWorker>(workerUrl, {
maxWorkers: 4,
warmUpWorkers: true,
workerOptions: { type: 'module' },
});
// terminate idle Workers after five seconds without work
export const frugal = () =>
createWorker<MathWorker>(workerUrl, {
maxWorkers: 4,
keepAlive: false,
terminationDelay: 5_000,
workerOptions: { type: 'module' },
});| Option | Default | Purpose |
|---|---|---|
maxWorkers | 1 | Maximum number of native Workers |
warmUpWorkers | true for one Worker | Creates the pool during initialization |
keepAlive | Same as warmUpWorkers | Keeps idle Workers alive |
terminationDelay | 1000 ms | Wait before terminating idle Workers |
A single Worker is created up front and kept alive. A pool is created on demand and released when idle, unless you ask otherwise.
What a pool is good for
How many Workers to use depends on the device. navigator.hardwareConcurrency reports the logical cores; leaving
one for the main thread is a reasonable start.
Bring your own pool
An array of native Workers is used as the pool, as it is. See Creating workers.
Try it
The worker pool example searches three segments of numbers with one Worker and then with three.