batch-cluster
Version:
Manage a cluster of child processes
129 lines • 5.39 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 _TaskQueueManager_tasks, _TaskQueueManager_logger;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TaskQueueManager = void 0;
/**
* Manages task queuing, scheduling, and assignment to ready processes.
* Handles the task lifecycle from enqueue to assignment.
*/
class TaskQueueManager {
constructor(logger, emitter) {
this.emitter = emitter;
_TaskQueueManager_tasks.set(this, []);
_TaskQueueManager_logger.set(this, void 0);
__classPrivateFieldSet(this, _TaskQueueManager_logger, logger, "f");
}
/**
* Add a task to the queue for processing
*/
enqueueTask(task, ended) {
if (ended) {
task.reject(new Error("BatchCluster has ended, cannot enqueue " + task.command));
}
else {
__classPrivateFieldGet(this, _TaskQueueManager_tasks, "f").push(task);
}
return task.promise;
}
/**
* Simple enqueue method (alias for enqueueTask without ended check)
*/
enqueue(task) {
__classPrivateFieldGet(this, _TaskQueueManager_tasks, "f").push(task);
}
/**
* Get the number of pending tasks in the queue
*/
get pendingTaskCount() {
return __classPrivateFieldGet(this, _TaskQueueManager_tasks, "f").length;
}
/**
* Get all pending tasks (mostly for testing)
*/
get pendingTasks() {
return __classPrivateFieldGet(this, _TaskQueueManager_tasks, "f");
}
/**
* Check if the queue is empty
*/
get isEmpty() {
return __classPrivateFieldGet(this, _TaskQueueManager_tasks, "f").length === 0;
}
/**
* Attempt to assign the next task to a ready process.
* Returns true if a task was successfully assigned.
*/
tryAssignNextTask(readyProcess, retries = 1) {
var _a;
if (__classPrivateFieldGet(this, _TaskQueueManager_tasks, "f").length === 0 || retries < 0) {
return false;
}
// no procs are idle and healthy :(
if (readyProcess == null) {
return false;
}
const task = __classPrivateFieldGet(this, _TaskQueueManager_tasks, "f").shift();
if (task == null) {
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit("internalError", new Error("unexpected null task"));
return false;
}
const submitted = readyProcess.execTask(task);
if (!submitted) {
// This isn't an internal error: the proc may have needed to run a health
// check. Let's reschedule the task and try again:
__classPrivateFieldGet(this, _TaskQueueManager_tasks, "f").push(task);
// We don't want to return false here (it'll stop the assignment loop) unless
// we actually can't submit the task:
return this.tryAssignNextTask(readyProcess, retries - 1);
}
__classPrivateFieldGet(this, _TaskQueueManager_logger, "f").call(this).trace("TaskQueueManager.tryAssignNextTask(): submitted task", {
child_pid: readyProcess.pid,
task,
});
return submitted;
}
/**
* Process all pending tasks by assigning them to ready processes.
* Returns the number of tasks successfully assigned.
*/
processQueue(findReadyProcess) {
let assignedCount = 0;
while (__classPrivateFieldGet(this, _TaskQueueManager_tasks, "f").length > 0) {
const readyProcess = findReadyProcess();
if (!this.tryAssignNextTask(readyProcess)) {
break;
}
assignedCount++;
}
return assignedCount;
}
/**
* Clear all pending tasks (used during shutdown)
*/
clearAllTasks() {
__classPrivateFieldGet(this, _TaskQueueManager_tasks, "f").length = 0;
}
/**
* Get statistics about task assignment and queue state
*/
getQueueStats() {
return {
pendingTaskCount: __classPrivateFieldGet(this, _TaskQueueManager_tasks, "f").length,
isEmpty: this.isEmpty,
};
}
}
exports.TaskQueueManager = TaskQueueManager;
_TaskQueueManager_tasks = new WeakMap(), _TaskQueueManager_logger = new WeakMap();
//# sourceMappingURL=TaskQueueManager.js.map