parallel-universe
Version:
The set of async flow control structures and promise utils.
58 lines (54 loc) • 1.79 kB
JavaScript
;
var utils = require('./utils.js');
/**
* The worker picks a job from the queue and invokes its callbacks to fulfill or reject the underlying promise.
*/
class Worker {
/**
* Creates a new {@link Worker} instance.
*
* @param jobQueue The queue from which the worker takes jobs.
*/
constructor(jobQueue) {
/**
* `true` if the worker won't consume any new jobs, or `false` otherwise.
*/
this.isTerminated = false;
const next = () => {
const abortController = new AbortController();
this._abortController = abortController;
const signal = abortController.signal;
this._promise = jobQueue
.takeAck()
.withSignal(signal)
.then(([job, ack]) => {
if (signal.aborted || job.signal.aborted) {
ack(false);
return;
}
ack(true);
signal.addEventListener('abort', () => {
job.reject(signal.reason);
});
job.signal.addEventListener('abort', () => {
abortController.abort(job.signal.reason);
});
return new Promise(resolve => {
resolve(utils.withSignal((0, job.cb)(signal), signal));
}).then(job.resolve, job.reject);
}, utils.noop)
.then(() => {
if (!this.isTerminated) {
next();
}
});
};
next();
}
terminate(reason) {
this._abortController.abort(reason);
this.isTerminated = true;
return this._promise;
}
}
exports.Worker = Worker;