123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- /**
- * Helper class to push actions to a pool of workers.
- */
- export class WorkerPool {
- /**
- * Constructor
- * @param workers Array of workers to use for actions
- */
- constructor(workers) {
- this._pendingActions = new Array();
- this._workerInfos = workers.map((worker) => ({
- workerPromise: Promise.resolve(worker),
- idle: true,
- }));
- }
- /**
- * Terminates all workers and clears any pending actions.
- */
- dispose() {
- for (const workerInfo of this._workerInfos) {
- workerInfo.workerPromise.then((worker) => {
- worker.terminate();
- });
- }
- this._workerInfos.length = 0;
- this._pendingActions.length = 0;
- }
- /**
- * Pushes an action to the worker pool. If all the workers are active, the action will be
- * pended until a worker has completed its action.
- * @param action The action to perform. Call onComplete when the action is complete.
- */
- push(action) {
- if (!this._executeOnIdleWorker(action)) {
- this._pendingActions.push(action);
- }
- }
- _executeOnIdleWorker(action) {
- for (const workerInfo of this._workerInfos) {
- if (workerInfo.idle) {
- this._execute(workerInfo, action);
- return true;
- }
- }
- return false;
- }
- _execute(workerInfo, action) {
- workerInfo.idle = false;
- workerInfo.workerPromise.then((worker) => {
- action(worker, () => {
- const nextAction = this._pendingActions.shift();
- if (nextAction) {
- this._execute(workerInfo, nextAction);
- }
- else {
- workerInfo.idle = true;
- }
- });
- });
- }
- }
- /**
- * Similar to the WorkerPool class except it creates and destroys workers automatically with a maximum of `maxWorkers` workers.
- * Workers are terminated when it is idle for at least `idleTimeElapsedBeforeRelease` milliseconds.
- */
- export class AutoReleaseWorkerPool extends WorkerPool {
- constructor(maxWorkers, createWorkerAsync, options = AutoReleaseWorkerPool.DefaultOptions) {
- super([]);
- this._maxWorkers = maxWorkers;
- this._createWorkerAsync = createWorkerAsync;
- this._options = options;
- }
- push(action) {
- if (!this._executeOnIdleWorker(action)) {
- if (this._workerInfos.length < this._maxWorkers) {
- const workerInfo = {
- workerPromise: this._createWorkerAsync(),
- idle: false,
- };
- this._workerInfos.push(workerInfo);
- this._execute(workerInfo, action);
- }
- else {
- this._pendingActions.push(action);
- }
- }
- }
- _execute(workerInfo, action) {
- // Reset the idle timeout.
- if (workerInfo.timeoutId) {
- clearTimeout(workerInfo.timeoutId);
- delete workerInfo.timeoutId;
- }
- super._execute(workerInfo, (worker, onComplete) => {
- action(worker, () => {
- onComplete();
- if (workerInfo.idle) {
- // Schedule the worker to be terminated after the elapsed time.
- workerInfo.timeoutId = setTimeout(() => {
- workerInfo.workerPromise.then((worker) => {
- worker.terminate();
- });
- const indexOf = this._workerInfos.indexOf(workerInfo);
- if (indexOf !== -1) {
- this._workerInfos.splice(indexOf, 1);
- }
- }, this._options.idleTimeElapsedBeforeRelease);
- }
- });
- });
- }
- }
- /**
- * Default options for the constructor.
- * Override to change the defaults.
- */
- AutoReleaseWorkerPool.DefaultOptions = {
- idleTimeElapsedBeforeRelease: 1000,
- };
- //# sourceMappingURL=workerPool.js.map
|