rc-js-util
Version:
A collection of TS and C++ utilities to help writing performant and correct applications, achieved through strict typing and (removable) invariant checking.
117 lines • 4.75 kB
TypeScript
import { IEmscriptenWrapper } from "../emscripten/i-emscripten-wrapper.js";
import type { IWorkerPoolBindings } from "./i-worker-pool-bindings.js";
import { type IManagedObject, type IManagedResourceNode, type IPointer } from "../../lifecycle/manged-resources.js";
/**
* @public
* How to handle jobs which don't "overflow", i.e. the workers cannot keep up with the work being sent.
*/
export declare enum EWorkerPoolOverflowMode {
/**
* Delete the job and then throw a {@link NestedError} with a cause of {@link WorkerPoolErrorCause.overflow}.
* @remarks This is intended mainly for unit tests.
* @remarks Ownership of the job is transferred to the job queue.
*/
Throw = 1,
/**
* If no worker is able to accept the job, the job runs on the producer (caller) thread. This automatically
* "fixes" backpressure by throttling the caller thread. This will result in degraded performance on the producer thread
* (often the UI thread) which is not always desirable.
* @remarks {@link IWorkerPool.addJob} will return false where the job ran synchronously.
* @remarks Ownership of the job is transferred to the job queue.
*/
Synchronous = 2,
/**
* Do nothing, it's up to you to choose an action.
* @remarks {@link IWorkerPool.addJob} will return false where the job did not run.
* @remarks Ownership of the job is NOT transferred to the job queue, the caller must clean up.
*/
Noop = 3
}
/**
* @public
* The static members are the cause in {@link INestedError}.
*/
export declare class WorkerPoolErrorCause {
static readonly overflow = "WorkerPoolErrorCause.overflow";
}
/**
* @public
* Configuration for a {@link IWorkerPool}.
*/
export interface IWorkerPoolConfig {
/**
* The number of threads in the pool.
*/
readonly workerCount: number;
/**
* The number of jobs each thread can buffer.
* Tune this in conjunction with the distribution strategy, # of workers and queue size to meet your needs.
*/
readonly queueSize: number;
readonly overflowMode?: EWorkerPoolOverflowMode;
}
/**
* @public
* A shared pool of web workers to run jobs off the main thread.
* @remarks The pool should be stopped before being destroyed to avoid deadlocks.
* @remarks Use the batching system to work out when a particular set of jobs has been completed.
* @remarks If you know the number of threads you need, use `-sPTHREAD_POOL_SIZE=` to allocate them up front.
*/
export interface IWorkerPool extends IManagedObject, IPointer {
/**
* @returns The number of workers that started.
*/
start(): Promise<number>;
stop(): Promise<void>;
isRunning(): boolean;
/**
* Transfer unique ownership of the job to the pool. If the pool is running, the job should eventually be run.
* @remarks The job is deleted on completion.
*/
addJob(jobPtr: number): boolean;
/**
* True if there is any job which has yet to be run. The answer is guaranteed correct on the producer thread.
*/
hasPendingWork(): boolean;
/**
* After adding jobs, you can mark the last job on each worker to track when they have all be completed using {@link IWorkerPool.isBatchDone}.
*/
setBatchEnd(): void;
/**
* This can be polled using {@link promisePoll}.;
*/
isBatchDone(): boolean;
/**
* Cancel any outstanding jobs, does not kill the current job (which must complete first).
*/
invalidateBatch(): void;
/**
* Becomes true once only "valid" jobs are running i.e. all the invalid jobs are gone - use in combination with
* {@link IWorkerPool.invalidateBatch}.
*/
areWorkersSynced(): boolean;
}
/**
* @public
* {@inheritDoc IWorkerPool}
*/
export declare class WorkerPool implements IWorkerPool {
private readonly wrapper;
static createRoundRobin(wrapper: IEmscriptenWrapper<IWorkerPoolBindings>, config: IWorkerPoolConfig, bindToReference: IManagedResourceNode | null, allocationFailThrows: boolean): WorkerPool | null;
static createRoundRobin(wrapper: IEmscriptenWrapper<IWorkerPoolBindings>, config: IWorkerPoolConfig, bindToReference: IManagedResourceNode | null): IWorkerPool;
readonly resourceHandle: IManagedResourceNode;
readonly pointer: number;
getWrapper(): IEmscriptenWrapper<IWorkerPoolBindings>;
start(): Promise<number>;
stop(): Promise<void>;
isRunning(): boolean;
isBatchDone(): boolean;
setBatchEnd(): void;
invalidateBatch(): void;
areWorkersSynced(): boolean;
hasPendingWork(): boolean;
addJob(jobPtr: number): boolean;
private readonly overflowMode;
private readonly cleanup;
}
//# sourceMappingURL=worker-pool.d.ts.map