batch-cluster
Version:
Manage a cluster of child processes
63 lines • 1.84 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.Mutex = void 0;
const Array_1 = require("./Array");
const Deferred_1 = require("./Deferred");
/**
* Aggregate promises efficiently
*/
class Mutex {
constructor() {
this._pushCount = 0;
this._arr = [];
}
get arr() {
(0, Array_1.filterInPlace)(this._arr, (ea) => ea.pending);
return this._arr;
}
get pushCount() {
return this._pushCount;
}
push(f) {
this._pushCount++;
const p = f();
// Don't cause awaitAll to die if a task rejects:
this.arr.push(new Deferred_1.Deferred().observeQuietly(p));
return p;
}
/**
* Run f() after all prior-enqueued promises have resolved.
*/
serial(f) {
return this.push(() => this.awaitAll().then(() => f()));
}
/**
* Only run f() if all prior have finished, otherwise, no-op and wait until
* all pending have resolved.
*/
runIfIdle(f) {
return this.pending ? undefined : this.serial(f);
}
get pendingCount() {
// Don't need vacuuming, so we can use this._arr:
return this._arr.reduce((sum, ea) => sum + (ea.pending ? 1 : 0), 0);
}
get pending() {
return this.pendingCount > 0;
}
get settled() {
// this.arr is a getter that does vacuuming
return this.arr.length === 0;
}
/**
* @return a promise that will be resolved when all previously-pushed Promises
* are resolved. Any promise rejection will throw the whole chain.
*/
awaitAll() {
return this.arr.length === 0
? Promise.resolve(undefined)
: Promise.all(this.arr.map((ea) => ea.promise)).then(() => undefined);
}
}
exports.Mutex = Mutex;
//# sourceMappingURL=Mutex.js.map
;