batch-cluster
Version:
Manage a cluster of child processes
97 lines • 5.4 kB
JavaScript
"use strict";
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var _Rate_instances, _Rate_start, _Rate_priorEventTimestamps, _Rate_lastEventTs, _Rate_eventCount, _Rate_vacuum;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Rate = void 0;
const BatchClusterOptions_1 = require("./BatchClusterOptions");
// Implementation notes:
// The prior implementation relied on a weighted average of milliseconds between
// events, which didn't behave well when a series of events happend in the same
// millisecond, and didn't correctly recover if events ceased completely (which
// would be expected if this was an error or timeout rate).
// Keeping each event time in an array makes these calculations more precise,
// but suffers from more memory consumption when measuring high rates and using
// a large periodMs.
class Rate {
/**
* @param periodMs the length of time to retain event timestamps for computing
* rate. Events older than this value will be discarded.
* @param warmupMs return `null` from {@link Rate#msPerEvent} if it's been less
* than `warmupMs` since construction or {@link Rate#clear}.
*/
constructor(periodMs = BatchClusterOptions_1.minuteMs, warmupMs = BatchClusterOptions_1.secondMs) {
_Rate_instances.add(this);
this.periodMs = periodMs;
this.warmupMs = warmupMs;
_Rate_start.set(this, Date.now());
_Rate_priorEventTimestamps.set(this, []);
_Rate_lastEventTs.set(this, null);
_Rate_eventCount.set(this, 0
/**
* @param periodMs the length of time to retain event timestamps for computing
* rate. Events older than this value will be discarded.
* @param warmupMs return `null` from {@link Rate#msPerEvent} if it's been less
* than `warmupMs` since construction or {@link Rate#clear}.
*/
);
}
onEvent() {
var _a;
__classPrivateFieldSet(this, _Rate_eventCount, (_a = __classPrivateFieldGet(this, _Rate_eventCount, "f"), _a++, _a), "f");
const now = Date.now();
__classPrivateFieldGet(this, _Rate_priorEventTimestamps, "f").push(now);
__classPrivateFieldSet(this, _Rate_lastEventTs, now, "f");
}
get eventCount() {
return __classPrivateFieldGet(this, _Rate_eventCount, "f");
}
get msSinceLastEvent() {
return __classPrivateFieldGet(this, _Rate_lastEventTs, "f") == null ? null : Date.now() - __classPrivateFieldGet(this, _Rate_lastEventTs, "f");
}
get msPerEvent() {
const msSinceStart = Date.now() - __classPrivateFieldGet(this, _Rate_start, "f");
if (__classPrivateFieldGet(this, _Rate_lastEventTs, "f") == null || msSinceStart < this.warmupMs)
return null;
__classPrivateFieldGet(this, _Rate_instances, "m", _Rate_vacuum).call(this);
const events = __classPrivateFieldGet(this, _Rate_priorEventTimestamps, "f").length;
return events === 0 ? null : Math.min(this.periodMs, msSinceStart) / events;
}
get eventsPerMs() {
const mpe = this.msPerEvent;
return mpe == null ? 0 : mpe < 1 ? 1 : 1 / mpe;
}
get eventsPerSecond() {
return this.eventsPerMs * BatchClusterOptions_1.secondMs;
}
get eventsPerMinute() {
return this.eventsPerMs * BatchClusterOptions_1.minuteMs;
}
clear() {
__classPrivateFieldSet(this, _Rate_start, Date.now(), "f");
__classPrivateFieldGet(this, _Rate_priorEventTimestamps, "f").length = 0;
__classPrivateFieldSet(this, _Rate_lastEventTs, null, "f");
__classPrivateFieldSet(this, _Rate_eventCount, 0, "f");
return this;
}
}
exports.Rate = Rate;
_Rate_start = new WeakMap(), _Rate_priorEventTimestamps = new WeakMap(), _Rate_lastEventTs = new WeakMap(), _Rate_eventCount = new WeakMap(), _Rate_instances = new WeakSet(), _Rate_vacuum = function _Rate_vacuum() {
const expired = Date.now() - this.periodMs;
const firstValidIndex = __classPrivateFieldGet(this, _Rate_priorEventTimestamps, "f").findIndex((ea) => ea > expired);
if (firstValidIndex === -1)
__classPrivateFieldGet(this, _Rate_priorEventTimestamps, "f").length = 0;
else if (firstValidIndex > 0) {
__classPrivateFieldGet(this, _Rate_priorEventTimestamps, "f").splice(0, firstValidIndex);
}
};
//# sourceMappingURL=Rate.js.map