batch-cluster
Advanced tools
Comparing version 9.0.1 to 9.1.0
@@ -21,2 +21,10 @@ # Changelog | ||
## v9.1.0 | ||
- 🐞/📦 `BatchProcess` exposes a promise for the completion of the startup task, | ||
which `BatchCluster` now uses to immediately run `#onIdle` and pop off any | ||
pending work. | ||
- 📦 Updated development dependencies and rebuild docs | ||
## v9.0.1 | ||
@@ -23,0 +31,0 @@ |
@@ -47,3 +47,3 @@ /// <reference types="node" /> | ||
*/ | ||
readonly on: <E extends keyof BatchClusterEvents>(event: E, listener: (...args: BatchClusterEvents[E] extends (...args: infer A) => void ? A : never) => void) => BatchClusterEmitter; | ||
readonly on: <E extends keyof BatchClusterEvents>(eventName: E, listener: (...args: BatchClusterEvents[E] extends (...args: infer A) => void ? A : never) => void) => BatchClusterEmitter; | ||
/** | ||
@@ -53,3 +53,3 @@ * @see BatchClusterEvents | ||
*/ | ||
readonly off: <E extends keyof BatchClusterEvents>(event: E, listener: (...args: BatchClusterEvents[E] extends (...args: infer A) => void ? A : never) => void) => BatchClusterEmitter; | ||
readonly off: <E extends keyof BatchClusterEvents>(eventName: E, listener: (...args: BatchClusterEvents[E] extends (...args: infer A) => void ? A : never) => void) => BatchClusterEmitter; | ||
get ended(): boolean; | ||
@@ -129,3 +129,2 @@ /** | ||
setMaxProcs(maxProcs: number): void; | ||
private onIdle; | ||
/** | ||
@@ -132,0 +131,0 @@ * Run maintenance on currently spawned child processes. This method is |
@@ -26,3 +26,3 @@ "use strict"; | ||
}; | ||
var _BatchCluster_instances, _BatchCluster_tasksPerProc, _BatchCluster_logger, _BatchCluster_procs, _BatchCluster_lastSpawnedProcTime, _BatchCluster_lastPidsCheckTime, _BatchCluster_tasks, _BatchCluster_onIdleInterval, _BatchCluster_startErrorRate, _BatchCluster_spawnedProcs, _BatchCluster_endPromise, _BatchCluster_internalErrorCount, _BatchCluster_childEndCounts, _BatchCluster_beforeExitListener, _BatchCluster_exitListener, _BatchCluster_maybeCheckPids, _BatchCluster_execNextTask, _BatchCluster_maybeLaunchNewChild, _BatchCluster_spawnChild; | ||
var _BatchCluster_instances, _BatchCluster_tasksPerProc, _BatchCluster_logger, _BatchCluster_procs, _BatchCluster_lastSpawnedProcTime, _BatchCluster_lastPidsCheckTime, _BatchCluster_tasks, _BatchCluster_onIdleInterval, _BatchCluster_startErrorRate, _BatchCluster_spawnedProcs, _BatchCluster_endPromise, _BatchCluster_internalErrorCount, _BatchCluster_childEndCounts, _BatchCluster_beforeExitListener, _BatchCluster_exitListener, _BatchCluster_onIdleLater, _BatchCluster_onIdle, _BatchCluster_maybeCheckPids, _BatchCluster_execNextTask, _BatchCluster_maybeLaunchNewChild, _BatchCluster_spawnChild; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -91,2 +91,5 @@ exports.BatchCluster = exports.Task = exports.pids = exports.pidExists = exports.kill = exports.SimpleParser = exports.Deferred = exports.BatchClusterOptions = void 0; | ||
_BatchCluster_exitListener.set(this, () => this.end(false)); | ||
_BatchCluster_onIdleLater.set(this, () => setImmediate(() => __classPrivateFieldGet(this, _BatchCluster_instances, "m", _BatchCluster_onIdle).call(this)) | ||
// NOT ASYNC: updates internal state: | ||
); | ||
this.options = (0, BatchClusterOptions_1.verifyOptions)({ ...opts, observer: this.emitter }); | ||
@@ -111,3 +114,3 @@ this.on("internalError", (error) => { | ||
if (this.options.onIdleIntervalMillis > 0) { | ||
__classPrivateFieldSet(this, _BatchCluster_onIdleInterval, timers_1.default.setInterval(() => this.onIdle(), this.options.onIdleIntervalMillis), "f"); | ||
__classPrivateFieldSet(this, _BatchCluster_onIdleInterval, timers_1.default.setInterval(() => __classPrivateFieldGet(this, _BatchCluster_instances, "m", _BatchCluster_onIdle).call(this), this.options.onIdleIntervalMillis), "f"); | ||
__classPrivateFieldGet(this, _BatchCluster_onIdleInterval, "f").unref(); // < don't prevent node from exiting | ||
@@ -156,4 +159,4 @@ } | ||
__classPrivateFieldGet(this, _BatchCluster_tasks, "f").push(task); | ||
setImmediate(() => this.onIdle()); | ||
return task.promise.finally(() => this.onIdle()); | ||
__classPrivateFieldGet(this, _BatchCluster_onIdleLater, "f").call(this); | ||
return task.promise.finally(__classPrivateFieldGet(this, _BatchCluster_onIdleLater, "f")); | ||
} | ||
@@ -266,12 +269,4 @@ /** | ||
// we may now be able to handle an enqueued task. Vacuum pids and see: | ||
this.onIdle(); | ||
__classPrivateFieldGet(this, _BatchCluster_instances, "m", _BatchCluster_onIdle).call(this); | ||
} | ||
// NOT ASYNC: updates internal state: | ||
onIdle() { | ||
this.vacuumProcs(); | ||
while (__classPrivateFieldGet(this, _BatchCluster_instances, "m", _BatchCluster_execNextTask).call(this)) { | ||
// | ||
} | ||
__classPrivateFieldGet(this, _BatchCluster_instances, "m", _BatchCluster_maybeLaunchNewChild).call(this); | ||
} | ||
/** | ||
@@ -300,3 +295,9 @@ * Run maintenance on currently spawned child processes. This method is | ||
exports.BatchCluster = BatchCluster; | ||
_BatchCluster_tasksPerProc = new WeakMap(), _BatchCluster_logger = new WeakMap(), _BatchCluster_procs = new WeakMap(), _BatchCluster_lastSpawnedProcTime = new WeakMap(), _BatchCluster_lastPidsCheckTime = new WeakMap(), _BatchCluster_tasks = new WeakMap(), _BatchCluster_onIdleInterval = new WeakMap(), _BatchCluster_startErrorRate = new WeakMap(), _BatchCluster_spawnedProcs = new WeakMap(), _BatchCluster_endPromise = new WeakMap(), _BatchCluster_internalErrorCount = new WeakMap(), _BatchCluster_childEndCounts = new WeakMap(), _BatchCluster_beforeExitListener = new WeakMap(), _BatchCluster_exitListener = new WeakMap(), _BatchCluster_instances = new WeakSet(), _BatchCluster_maybeCheckPids = function _BatchCluster_maybeCheckPids() { | ||
_BatchCluster_tasksPerProc = new WeakMap(), _BatchCluster_logger = new WeakMap(), _BatchCluster_procs = new WeakMap(), _BatchCluster_lastSpawnedProcTime = new WeakMap(), _BatchCluster_lastPidsCheckTime = new WeakMap(), _BatchCluster_tasks = new WeakMap(), _BatchCluster_onIdleInterval = new WeakMap(), _BatchCluster_startErrorRate = new WeakMap(), _BatchCluster_spawnedProcs = new WeakMap(), _BatchCluster_endPromise = new WeakMap(), _BatchCluster_internalErrorCount = new WeakMap(), _BatchCluster_childEndCounts = new WeakMap(), _BatchCluster_beforeExitListener = new WeakMap(), _BatchCluster_exitListener = new WeakMap(), _BatchCluster_onIdleLater = new WeakMap(), _BatchCluster_instances = new WeakSet(), _BatchCluster_onIdle = function _BatchCluster_onIdle() { | ||
this.vacuumProcs(); | ||
while (__classPrivateFieldGet(this, _BatchCluster_instances, "m", _BatchCluster_execNextTask).call(this)) { | ||
// | ||
} | ||
__classPrivateFieldGet(this, _BatchCluster_instances, "m", _BatchCluster_maybeLaunchNewChild).call(this); | ||
}, _BatchCluster_maybeCheckPids = function _BatchCluster_maybeCheckPids() { | ||
if (this.options.pidCheckIntervalMillis > 0 && | ||
@@ -376,2 +377,4 @@ __classPrivateFieldGet(this, _BatchCluster_lastPidsCheckTime, "f") + this.options.pidCheckIntervalMillis < Date.now()) { | ||
__classPrivateFieldGet(this, _BatchCluster_procs, "f").push(proc); | ||
// As soon as this is ready, run onIdle | ||
proc.startupPromise.then(__classPrivateFieldGet(this, _BatchCluster_onIdleLater, "f"), __classPrivateFieldGet(this, _BatchCluster_onIdleLater, "f")); | ||
return proc; | ||
@@ -378,0 +381,0 @@ } |
@@ -5,2 +5,11 @@ /// <reference types="node" /> | ||
import { Task } from "./Task"; | ||
declare type Args<T> = T extends (...args: infer A) => void ? A : never; | ||
export interface TypedEventEmitter<T> { | ||
once<E extends keyof T>(eventName: E, listener: (...args: Args<T[E]>) => void): this; | ||
on<E extends keyof T>(eventName: E, listener: (...args: Args<T[E]>) => void): this; | ||
off<E extends keyof T>(eventName: E, listener: (...args: Args<T[E]>) => void): this; | ||
emit<E extends keyof T>(eventName: E, ...args: Args<T[E]>): boolean; | ||
listeners<E extends keyof T>(event: E): Function[]; | ||
removeAllListeners(eventName?: keyof T): this; | ||
} | ||
/** | ||
@@ -69,3 +78,2 @@ * This interface describes the BatchCluster's event names as fields. The type | ||
} | ||
declare type Args<E extends keyof BatchClusterEvents> = BatchClusterEvents[E] extends (...args: infer A) => void ? A : never; | ||
/** | ||
@@ -91,7 +99,3 @@ * The BatchClusterEmitter signature is built up automatically by the | ||
*/ | ||
export interface BatchClusterEmitter { | ||
on<E extends keyof BatchClusterEvents>(event: E, listener: (...args: Args<E>) => void): this; | ||
off<E extends keyof BatchClusterEvents>(event: E, listener: (...args: Args<E>) => void): this; | ||
emit<E extends keyof BatchClusterEvents>(event: E, ...args: Args<E>): boolean; | ||
} | ||
export declare type BatchClusterEmitter = TypedEventEmitter<BatchClusterEvents>; | ||
export {}; |
@@ -33,3 +33,3 @@ import { ChildProcessFactory } from "./BatchCluster"; | ||
* | ||
* Must be > 0. Defaults to 5 seconds. | ||
* Must be > 0. Defaults to 10 seconds. | ||
*/ | ||
@@ -36,0 +36,0 @@ onIdleIntervalMillis: number; |
@@ -37,5 +37,5 @@ "use strict"; | ||
* | ||
* Must be > 0. Defaults to 5 seconds. | ||
* Must be > 0. Defaults to 10 seconds. | ||
*/ | ||
this.onIdleIntervalMillis = 5 * secondMs; | ||
this.onIdleIntervalMillis = 10 * secondMs; | ||
/** | ||
@@ -42,0 +42,0 @@ * If the initial `versionCommand` fails for new spawned processes more |
@@ -16,5 +16,5 @@ /// <reference types="node" /> | ||
readonly start: number; | ||
readonly startupTaskId: number; | ||
failedTaskCount: number; | ||
constructor(proc: _cp.ChildProcess, opts: InternalBatchProcessOptions); | ||
get startupPromise(): Promise<void>; | ||
get currentTask(): Task | undefined; | ||
@@ -21,0 +21,0 @@ get taskCount(): number; |
@@ -13,3 +13,3 @@ "use strict"; | ||
}; | ||
var _BatchProcess_instances, _BatchProcess_lastHealthCheck, _BatchProcess_healthCheckFailures, _BatchProcess_logger, _BatchProcess_lastJobFinshedAt, _BatchProcess_dead, _BatchProcess_taskCount, _BatchProcess_ending, _BatchProcess_resolvedOnExit, _BatchProcess_currentTask, _BatchProcess_currentTaskTimeout, _BatchProcess_execTask, _BatchProcess_end, _BatchProcess_awaitNotRunning, _BatchProcess_onTimeout, _BatchProcess_onError, _BatchProcess_onExit, _BatchProcess_onStderr, _BatchProcess_onStdout, _BatchProcess_clearCurrentTask; | ||
var _BatchProcess_instances, _BatchProcess_lastHealthCheck, _BatchProcess_healthCheckFailures, _BatchProcess_startupTask, _BatchProcess_logger, _BatchProcess_lastJobFinshedAt, _BatchProcess_dead, _BatchProcess_taskCount, _BatchProcess_ending, _BatchProcess_resolvedOnExit, _BatchProcess_currentTask, _BatchProcess_currentTaskTimeout, _BatchProcess_execTask, _BatchProcess_end, _BatchProcess_awaitNotRunning, _BatchProcess_onTimeout, _BatchProcess_onError, _BatchProcess_onExit, _BatchProcess_onStderr, _BatchProcess_onStdout, _BatchProcess_clearCurrentTask; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -37,2 +37,3 @@ exports.BatchProcess = void 0; | ||
_BatchProcess_healthCheckFailures.set(this, 0); | ||
_BatchProcess_startupTask.set(this, void 0); | ||
_BatchProcess_logger.set(this, void 0); | ||
@@ -89,5 +90,4 @@ _BatchProcess_lastJobFinshedAt.set(this, Date.now() | ||
}); | ||
const startupTask = new Task_1.Task(opts.versionCommand, Parser_1.SimpleParser); | ||
this.startupTaskId = startupTask.taskId; | ||
if (!this.execTask(startupTask)) { | ||
__classPrivateFieldSet(this, _BatchProcess_startupTask, new Task_1.Task(opts.versionCommand, Parser_1.SimpleParser), "f"); | ||
if (!this.execTask(__classPrivateFieldGet(this, _BatchProcess_startupTask, "f"))) { | ||
// This could also be considered a "start error", but if it's just an | ||
@@ -98,2 +98,5 @@ // internal bug and the process starts, don't veto because there's a bug: | ||
} | ||
get startupPromise() { | ||
return __classPrivateFieldGet(this, _BatchProcess_startupTask, "f").promise; | ||
} | ||
get currentTask() { | ||
@@ -257,3 +260,3 @@ return __classPrivateFieldGet(this, _BatchProcess_currentTask, "f"); | ||
exports.BatchProcess = BatchProcess; | ||
_BatchProcess_lastHealthCheck = new WeakMap(), _BatchProcess_healthCheckFailures = new WeakMap(), _BatchProcess_logger = new WeakMap(), _BatchProcess_lastJobFinshedAt = new WeakMap(), _BatchProcess_dead = new WeakMap(), _BatchProcess_taskCount = new WeakMap(), _BatchProcess_ending = new WeakMap(), _BatchProcess_resolvedOnExit = new WeakMap(), _BatchProcess_currentTask = new WeakMap(), _BatchProcess_currentTaskTimeout = new WeakMap(), _BatchProcess_instances = new WeakSet(), _BatchProcess_execTask = function _BatchProcess_execTask(task) { | ||
_BatchProcess_lastHealthCheck = new WeakMap(), _BatchProcess_healthCheckFailures = new WeakMap(), _BatchProcess_startupTask = new WeakMap(), _BatchProcess_logger = new WeakMap(), _BatchProcess_lastJobFinshedAt = new WeakMap(), _BatchProcess_dead = new WeakMap(), _BatchProcess_taskCount = new WeakMap(), _BatchProcess_ending = new WeakMap(), _BatchProcess_resolvedOnExit = new WeakMap(), _BatchProcess_currentTask = new WeakMap(), _BatchProcess_currentTaskTimeout = new WeakMap(), _BatchProcess_instances = new WeakSet(), _BatchProcess_execTask = function _BatchProcess_execTask(task) { | ||
var _a; | ||
@@ -266,3 +269,3 @@ var _b; | ||
const cmd = (0, String_1.ensureSuffix)(task.command, "\n"); | ||
const isStartupTask = task.taskId === this.startupTaskId; | ||
const isStartupTask = task.taskId === __classPrivateFieldGet(this, _BatchProcess_startupTask, "f").taskId; | ||
const timeoutMs = isStartupTask | ||
@@ -269,0 +272,0 @@ ? this.opts.spawnTimeoutMillis |
{ | ||
"name": "batch-cluster", | ||
"version": "9.0.1", | ||
"version": "9.1.0", | ||
"description": "Manage a cluster of child processes", | ||
@@ -37,15 +37,15 @@ "main": "dist/BatchCluster.js", | ||
"@types/chai": "^4.3.0", | ||
"@types/chai-as-promised": "^7.1.4", | ||
"@types/chai-as-promised": "^7.1.5", | ||
"@types/chai-string": "^1.4.2", | ||
"@types/mocha": "^9.1.0", | ||
"@types/node": "^17.0.10", | ||
"@typescript-eslint/eslint-plugin": "^5.10.0", | ||
"@typescript-eslint/parser": "^5.10.0", | ||
"chai": "^4.3.4", | ||
"@types/node": "^17.0.17", | ||
"@typescript-eslint/eslint-plugin": "^5.11.0", | ||
"@typescript-eslint/parser": "^5.11.0", | ||
"chai": "^4.3.6", | ||
"chai-as-promised": "^7.1.1", | ||
"chai-string": "^1.5.0", | ||
"chai-withintoleranceof": "^1.0.1", | ||
"eslint": "^8.7.0", | ||
"eslint": "^8.8.0", | ||
"eslint-plugin-import": "^2.25.4", | ||
"mocha": "^9.1.4", | ||
"mocha": "^9.2.0", | ||
"prettier": "^2.5.1", | ||
@@ -52,0 +52,0 @@ "rimraf": "^3.0.2", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
188239
2656