batch-cluster
Version:
Manage a cluster of child processes
138 lines • 9.23 kB
JavaScript
"use strict";
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 __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 _BatchClusterEventCoordinator_instances, _BatchClusterEventCoordinator_logger, _BatchClusterEventCoordinator_tasksPerProc, _BatchClusterEventCoordinator_startErrorRate, _BatchClusterEventCoordinator_childEndCounts, _BatchClusterEventCoordinator_internalErrorCount, _BatchClusterEventCoordinator_setupEventHandlers, _BatchClusterEventCoordinator_handleChildEnd, _BatchClusterEventCoordinator_handleInternalError, _BatchClusterEventCoordinator_handleNoTaskData, _BatchClusterEventCoordinator_handleStartError;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BatchClusterEventCoordinator = void 0;
const Mean_1 = require("./Mean");
const Rate_1 = require("./Rate");
const String_1 = require("./String");
/**
* Centralized coordinator for BatchCluster events.
* Handles event processing, statistics tracking, and automated responses to events.
*/
class BatchClusterEventCoordinator {
constructor(emitter, options, onIdleLater, endCluster) {
_BatchClusterEventCoordinator_instances.add(this);
this.emitter = emitter;
this.options = options;
this.onIdleLater = onIdleLater;
this.endCluster = endCluster;
_BatchClusterEventCoordinator_logger.set(this, void 0);
_BatchClusterEventCoordinator_tasksPerProc.set(this, new Mean_1.Mean());
_BatchClusterEventCoordinator_startErrorRate.set(this, new Rate_1.Rate());
_BatchClusterEventCoordinator_childEndCounts.set(this, new Map());
_BatchClusterEventCoordinator_internalErrorCount.set(this, 0);
__classPrivateFieldSet(this, _BatchClusterEventCoordinator_logger, options.logger, "f");
__classPrivateFieldGet(this, _BatchClusterEventCoordinator_instances, "m", _BatchClusterEventCoordinator_setupEventHandlers).call(this);
}
/**
* Get the mean number of tasks completed by child processes
*/
get meanTasksPerProc() {
const mean = __classPrivateFieldGet(this, _BatchClusterEventCoordinator_tasksPerProc, "f").mean;
return isNaN(mean) ? 0 : mean;
}
/**
* Get internal error count
*/
get internalErrorCount() {
return __classPrivateFieldGet(this, _BatchClusterEventCoordinator_internalErrorCount, "f");
}
/**
* Get start error rate per minute
*/
get startErrorRatePerMinute() {
return __classPrivateFieldGet(this, _BatchClusterEventCoordinator_startErrorRate, "f").eventsPerMinute;
}
/**
* Get count of ended child processes by reason
*/
countEndedChildProcs(reason) {
var _a;
return (_a = __classPrivateFieldGet(this, _BatchClusterEventCoordinator_childEndCounts, "f").get(reason)) !== null && _a !== void 0 ? _a : 0;
}
/**
* Get all child end counts
*/
get childEndCounts() {
return Object.fromEntries([...__classPrivateFieldGet(this, _BatchClusterEventCoordinator_childEndCounts, "f").entries()]);
}
/**
* Get event statistics for monitoring
*/
getEventStats() {
return {
meanTasksPerProc: this.meanTasksPerProc,
internalErrorCount: this.internalErrorCount,
startErrorRatePerMinute: this.startErrorRatePerMinute,
totalChildEndEvents: [...__classPrivateFieldGet(this, _BatchClusterEventCoordinator_childEndCounts, "f").values()].reduce((sum, count) => sum + count, 0),
childEndReasons: Object.keys(this.childEndCounts),
};
}
/**
* Reset event statistics (useful for testing)
*/
resetStats() {
__classPrivateFieldSet(this, _BatchClusterEventCoordinator_tasksPerProc, new Mean_1.Mean(), "f");
__classPrivateFieldSet(this, _BatchClusterEventCoordinator_startErrorRate, new Rate_1.Rate(), "f");
__classPrivateFieldGet(this, _BatchClusterEventCoordinator_childEndCounts, "f").clear();
__classPrivateFieldSet(this, _BatchClusterEventCoordinator_internalErrorCount, 0, "f");
}
/**
* Get the underlying emitter for direct event access
*/
get events() {
return this.emitter;
}
}
exports.BatchClusterEventCoordinator = BatchClusterEventCoordinator;
_BatchClusterEventCoordinator_logger = new WeakMap(), _BatchClusterEventCoordinator_tasksPerProc = new WeakMap(), _BatchClusterEventCoordinator_startErrorRate = new WeakMap(), _BatchClusterEventCoordinator_childEndCounts = new WeakMap(), _BatchClusterEventCoordinator_internalErrorCount = new WeakMap(), _BatchClusterEventCoordinator_instances = new WeakSet(), _BatchClusterEventCoordinator_setupEventHandlers = function _BatchClusterEventCoordinator_setupEventHandlers() {
this.emitter.on("childEnd", (bp, why) => __classPrivateFieldGet(this, _BatchClusterEventCoordinator_instances, "m", _BatchClusterEventCoordinator_handleChildEnd).call(this, bp, why));
this.emitter.on("internalError", (error) => __classPrivateFieldGet(this, _BatchClusterEventCoordinator_instances, "m", _BatchClusterEventCoordinator_handleInternalError).call(this, error));
this.emitter.on("noTaskData", (stdout, stderr, proc) => __classPrivateFieldGet(this, _BatchClusterEventCoordinator_instances, "m", _BatchClusterEventCoordinator_handleNoTaskData).call(this, stdout, stderr, proc));
this.emitter.on("startError", (error) => __classPrivateFieldGet(this, _BatchClusterEventCoordinator_instances, "m", _BatchClusterEventCoordinator_handleStartError).call(this, error));
}, _BatchClusterEventCoordinator_handleChildEnd = function _BatchClusterEventCoordinator_handleChildEnd(process, reason) {
var _a;
__classPrivateFieldGet(this, _BatchClusterEventCoordinator_tasksPerProc, "f").push(process.taskCount);
__classPrivateFieldGet(this, _BatchClusterEventCoordinator_childEndCounts, "f").set(reason, ((_a = __classPrivateFieldGet(this, _BatchClusterEventCoordinator_childEndCounts, "f").get(reason)) !== null && _a !== void 0 ? _a : 0) + 1);
this.onIdleLater();
}, _BatchClusterEventCoordinator_handleInternalError = function _BatchClusterEventCoordinator_handleInternalError(error) {
var _a;
__classPrivateFieldGet(this, _BatchClusterEventCoordinator_logger, "f").call(this).error("BatchCluster: INTERNAL ERROR: " + String(error));
__classPrivateFieldSet(this, _BatchClusterEventCoordinator_internalErrorCount, (_a = __classPrivateFieldGet(this, _BatchClusterEventCoordinator_internalErrorCount, "f"), _a++, _a), "f");
}, _BatchClusterEventCoordinator_handleNoTaskData = function _BatchClusterEventCoordinator_handleNoTaskData(stdout, stderr, proc) {
var _a;
__classPrivateFieldGet(this, _BatchClusterEventCoordinator_logger, "f").call(this).warn("BatchCluster: child process emitted data with no current task. Consider setting streamFlushMillis to a higher value.", {
streamFlushMillis: this.options.streamFlushMillis,
stdout: (0, String_1.toS)(stdout),
stderr: (0, String_1.toS)(stderr),
proc_pid: proc === null || proc === void 0 ? void 0 : proc.pid,
});
__classPrivateFieldSet(this, _BatchClusterEventCoordinator_internalErrorCount, (_a = __classPrivateFieldGet(this, _BatchClusterEventCoordinator_internalErrorCount, "f"), _a++, _a), "f");
}, _BatchClusterEventCoordinator_handleStartError = function _BatchClusterEventCoordinator_handleStartError(error) {
__classPrivateFieldGet(this, _BatchClusterEventCoordinator_logger, "f").call(this).warn("BatchCluster.onStartError(): " + String(error));
__classPrivateFieldGet(this, _BatchClusterEventCoordinator_startErrorRate, "f").onEvent();
if (this.options.maxReasonableProcessFailuresPerMinute > 0 &&
__classPrivateFieldGet(this, _BatchClusterEventCoordinator_startErrorRate, "f").eventsPerMinute >
this.options.maxReasonableProcessFailuresPerMinute) {
this.emitter.emit("fatalError", new Error(String(error) +
"(start errors/min: " +
__classPrivateFieldGet(this, _BatchClusterEventCoordinator_startErrorRate, "f").eventsPerMinute.toFixed(2) +
")"));
this.endCluster();
}
else {
this.onIdleLater();
}
};
//# sourceMappingURL=BatchClusterEventCoordinator.js.map