25 KiB
Changelog
Versioning
See Semver.
The MAJOR or API version is incremented for
- 💔 Non-backwards-compatible API changes
The MINOR or UPDATE version is incremented for
- ✨ Backwards-compatible features
The PATCH version is incremented for
-
🐞 Backwards-compatible bug fixes
-
📦 Minor packaging changes
v13.0.0
-
💔 Dropped official support for Node v16, which is EOL.
-
💔 Several methods, including BatchCluster#pids() were changed from async to sync (as they were needlessly async).
-
📦 A number of timeout options can now be validly 0 to disable timeouts:
spawnTimeoutMillistaskTimeoutMillis
-
📦 Added eslint
@typescript-eslint/await-thenablerule and delinted. -
📦 Updated development dependencies and rebuilt docs
v12.1.0
-
🐞
pidExistsnow handlesEPERMproperly (previous implementation would mischaracterize pids as being dead due to insufficient permissions) -
📦 Updated development dependencies and rebuilt docs
v12.0.0
-
💔/✨
pidExistsandkillPidare no longerasync, as process management is now performed vianode:process.kill(), instead of forkingpsortasklist. -
📦 Updated development dependencies and rebuilt docs
v11.0.0
- 💔 Drop official support for Node 12: EOL was 2022-04-30
v10.4.3
-
🐞 Fix support for zero value of
maxProcAgeMillis -
📦 Updated development dependencies and rebuilt docs
v10.4.2
-
🐞 Fix
unrefis not a function -
📦 Updated development dependencies and rebuilt docs
v10.4.1
- 📦 Improved concurrent event
Ratemeasurement.
v10.4.0
-
✨ If
healthCheckCommandis set and any task fails, that child process will have a health check run before being put back into rotation. -
📦 Updated development dependencies and rebuilt docs
v10.3.2
-
🐞
BatchCluster#maybeSpawnProcsin prior versions could spawn too many processes, especially if process startup was slow. Heuristics for when to spawn new processes now take into account pending task length and processes busy due to initial setup. -
📦
BatchCluster.vacuumProcsreturns a promise that is only fulfilled after all reaped child processes have completedBatchProcess.#end. -
📦
BatchProcess.whyNotHealthycan now returnstartError. -
📦
childEndis now emitted only after the child process exits -
📦
BatchCluster.#onIdleis debounced during the same event loop -
📦 Added startup and shutdown spec assertions
-
📦 Updated development dependencies and rebuilt docs
v10.3.1
-
📦 Add
Rate.msSinceLastEvent -
📦 Adjusted
streamFlushMillisto removeonTaskDataerrors in CI.
v10.3.0
-
✨ Exported
Rate. You might like it. -
✨ When child processes emit to
stdoutorstderrwith no current task, prior versions would emit aninternalError. These are now given their own newnoTaskDataevents. Consumers may want to bump upstreamFlushMillisif they see this in production. -
🐞/📦 Increased defaults for
streamFlushMillis, added tests to verifynoTaskDataevents don't happen in CI. -
📦 Normalized node imports
v10.2.0
-
✨/📦 Set
minDelayBetweenSpawnMillis = 0to fork child processes as soon as they are needed (rather than waiting betweenspawncalls) -
✨/📦 Set
maxReasonableProcessFailuresPerMinute = 0to disable process start error rate detection. -
✨/📦 New
fatalErrorevent emitted whenmaxReasonableProcessFailuresPerMinuteis exceeded and the instance shuts itself down. -
📦 New simpler
Rateimplementation with better time decay handling -
📦 Several jsdoc improvements, including exporting
WhyNotHeathyandWhyNotReady
v10.1.1
-
🐞 Fixed issue #15 by restoring the call to
#onIdleLaterwhen tasks settle. -
🐞 Fixed issue with
setMaxProcswhich resulted in all idle processes being reaped -
📦 The
idleevent was removed. You weren't using it, though, so I'm not bumping major. -
📦 Process shutdown is handled more gracefully with new
thenOrTimeout(rather than the priorPromise.racecall which resulted in a dangling timeout) -
📦 Updated development dependencies and rebuilt docs
v10.1.0
- 📦
.end()and.closeChildProcesses()closes all child processes in parallel
v10.0.1
- 📦 Export
BatchProcessinterface
v10.0.0
-
✨ Process state improvements
-
💔 Renamed event s/childExit/childEnd/
-
💔
childEndandchildStartevents receive BatchProcess instances now -
💔 Renamed healthy state s/dead/ended/
-
📦 Made BatchProcess.whyNotHealthy persistent
-
📦 Added several more WhyNotHealthy values
-
📦 Perf: filterInPlace and count use for loops rather than closures
-
📦 Added spec to verify
.endrejects long-running pending tasks -
📦 Updated development dependencies and rebuilt docs
v9.1.0
-
🐞/📦
BatchProcessexposes a promise for the completion of the startup task, whichBatchClusternow uses to immediately run#onIdleand pop off any pending work. -
📦 Updated development dependencies and rebuild docs
v9.0.1
- 📦 Don't emit
taskResolvedon startup tasks.
v9.0.0
-
💔 The
BatchProcessObserversignature was deleted, asBatchClusterEmitteris now typesafe. Consumers should not have used this signature directly, but in case anyone did, I bumped the major version. -
✨ Added
BatchCluster.offto unregister event listeners provided toBatchCluster.on. -
📦 Private fields and methods now use the
#private prefix rather than the TypeScriptprivatemodifier. -
📦 Minor tweaks (fixed several jsdoc errors, simplified some boolean logic, small reduction in promise chains, ...)
-
📦 Updated development dependencies and rebuild docs
v8.1.0
-
📦 Added
BatchCluster.procCountandBatchCluster.setMaxProcs, and newBatchCluster.ChildEndCountTypewhich includes a newtooManyvalue, which is incremented whensetMaxProcsis set to a smaller value. -
📦 Updated development dependencies
v8.0.1
-
🐞/📦 BatchProcess now end on spurious stderr/stdout, and reject tasks if ending.
-
📦 Relaxed default for
streamFlushMillisto deflake CI
v8.0.0
-
💔/📦 RegExp pass/fail strings are escaped (which could conceivably be a breaking change, hence the major version bump)
-
📦 Refactored stdout/stderr merging code and added more tests
-
📦 Added new "taskResolved" event
-
📦 Rebuild docs
-
📦 Updated development dependencies
v7.2.1
- 📦 Relax typing for optional
BatchProcessOptionsfields
v7.2.0
- 📦 Upgrade all dev dependencies. Pulling in new TypeScript 4.4 required redoing all node imports.
v7.1.0
-
✨ Added
on("healthCheckError", err, proc)event -
🐞 Fixed process start lag (due to startup tasks not emitting an
.onIdle) -
🐞 Reworked when health checks were run, and add tests to validate failing health checks recycle children
-
📦 Rebuild docs
v7.0.0
-
💔 Several fields were renamed to make things more consistent:
BatchCluster.pendingTaskswas renamed toBatchCluster.pendingTaskCount.- A new
BatchCluster.pendingTasksmethod now matchesBatchCluster.currentTasks, which both returnTask[]. BatchCluster.busyProcswas renamed tobusyProcCount.BatchCluster.spawnedProcswas renamed tospawnedProcCount.
-
✨ Added support for "health checks" that run periodically on child processes. Both
healthCheckCommandandhealthCheckIntervalMillismust be set to enable this feature. -
✨ New
pidCheckIntervalMillisto verify internal child process state is kept in sync with the process table. Defaults to every 2 minutes. Will no-op if idle. -
✨ New
BatchCluster.childEndCountsto report why child processes were recycled (currently "dead" | "ending" | "closed" | "worn" | "idle" | "broken" | "old" | "timeout" ) -
📦 Cleaned up scheduling: the prior implementation generated a bunch of
Promises per idle period, which was rough on the GC. Use ofMutexis now relegated to tests. -
📦
tsconfignow emitsES2018output and doesn't havedownlevelIteration, which reduces the size of the generated javascript, but requires contemporary versions of Node.js. -
📦
BatchClusterOptionsdoesn't mark fields asreadonlyanymore -
📦
Taskhas a default type ofanynow.
v6.2.1
- 📦 Added
BatchCluster.currentTasks
v6.2.0
- 📦 Updated development dependencies, which required handling undefined process ids.
v6.1.0
- ✨ Added
BatchCluster.closeChildProcesses()(ends child processes but doesn't.end()the BatchCluster instance) - 📦 Updated development dependencies
v6.0.2
- 📦 Include sourcemaps
- 📦 Updated development dependencies
v6.0.1
- 📦 Updated development dependencies
- 📦 Renamed
mainbranch - 📦 Hopefully fixed all typedoc URL changes
v6.0.0
No new features in v6: just a breaking change so we can fix an old name collision that caused linting errors.
-
💔 Prior versions name-collided on
Logger: both as aninterfaceand as a pseudonamespace for logger factories. This madeeslintgrumpy, and if anyone actually used this bare-bones logger, it could have caused confusion.Loggernow references only theinterface.The builder functions are now named
Log. -
📦 Updated development dependencies
v5.11.3
- 📦 Updated development dependencies (primarily TypeScript 4.1)
- 📦
Deferred.resolvenow requires an argument (as per the new Promise spec). As this is just a typing change (andDeferredis an internal implementation), I'm not bumping the major version.
v5.11.2
- 📦 Updated development dependencies
- 📦 Minor delint/prettier reformat
v5.11.1
- 📦 Updated development dependencies
v5.11.0
- ✨
BatchClustercan now be created with aLoggerthunk. - 📦 De-linted
- 📦 Updated development dependencies
- 📦 Add Node v14 to build matrix
v5.10.0
- ✨ New
maxIdleMsPerProcessoption: automatically shut down idle child processes to reduce system resource consumption. Defaults to0, which disables this feature (and prevents me from having to increment the major version!) - 📦 Updated development dependencies
v5.9.5
- 📦 Updated development dependencies
- 📦 Ran prettier (2.0.0 causes many no-op diffs due to changed defaults)
v5.9.4
- 📦 Updated development dependencies
v5.9.3
- 🐞
BatchProcess's streams could cause an infinite loop on.end()whenstdoutwas destroyed. - 📦 Updated development dependencies
v5.9.2
- 🐞
BatchProcess.readynow verifies the child process still exists - 📦 Replace tslint with eslint
- 📦 Updated development dependencies
v5.9.1
- 🐞 Errors after a process has shut down are logged and not propagated
- 📦 Updated development dependencies
v5.9.0
- 🐞 Moved all async throws into observables (to prevent "This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason...")
- 📦 Updated development dependencies
v5.8.0
- 🐞 Fixed issue where immediately closing a process before a pending task
completed resulted in
Error: onExit(exit) called end() - 📦 Updated development dependencies
v5.7.1
- 📦
BatchCluster.end()should return aDeferred<void>
v5.7.0
- 🐞 Fixed issue where
onStartErrorandonTaskErrordidn't get emitted. - 📦 Updated development dependencies, rebuilt docs.
- 🐞 Deflaked CI tests with longer timeouts and less aggressive
shutdown() - 📦 Had to delete the macOS Travis tests. Travis has been terribly flaky, with unreproduceable spec failures.
v5.6.8
- 📦 Updated development dependencies (new TypeScript)
v5.6.7
- 📦 Updated development dependencies
v5.6.6
- 📦 Updated development dependencies
v5.6.5
- 📦 wrapped
stdin.write()with try/catch that rejects the current task and closes the current process. - 📦 wrapped
stdin.end()with try/catch (as.writableisn't reliable)
v5.6.4
- 📦 Updated development dependencies
v5.6.3
- 📦 Moved to the PhotoStructure org. Updated URLs in docs.
v5.6.2
- 📦 Updated development dependencies
- 📦 Removed trace and debug log calls in
BatchProcess(which incurred GC overhead even when disabled)
v5.6.1
- 📦 Expose
BatchCluster.options. Note that the object is frozen at construction.
v5.6.0
- 🐞/✨
BatchProcess.end()didn't correctly implementgracefully(which resulted in spuriousend(): called while not idleerrors), and allowed for multiple calls to destroy and disconnect from the child process, which may or may not have been ill-advised.
v5.5.0
- ✨ Added
BatchCluster.isIdle. Updated development dependencies. Deflaked CI by embiggening - ✨ Added
BatchClusterOptions.cleanupChildProcs, in case you want to handle process cleanup yourself. - 📦 Updated development dependencies. Deflaked CI by embiggening timeouts.
- Happy 🥧 day.
v5.4.0
- ✨ "wear-leveling" for processes. Previously, only the first-spawned child process would service most task requests, but that caused issues with (very) long-running tasks where the other child processes would be spooled off ram, and could time out when requested later.
- 🐞
maxProcsis respected again. In prior builds, if tasks were enqueued all at once, prior dispatch code would only spin 1 concurrent task at a time. - 🐞 Multiple calls to
BatchProcess.endwould result in different promise resolution targets: the second call to.end()would resolve before the first. This was fixed. - ✨
BatchProcessOptions's
minDelayBetweenSpawnMilliswas added, to help relieve undue system load on startup. It defaults to 1.5 seconds and can be disabled by setting it to 0.
v5.3.1
- 📦 Removed
Deferred's warn log messages.
v5.3.0
- 🐞
.passand.failregex now support multiple line outputs per task.
v5.2.0
-
🐞 BatchProcessOptions
.passand.failhad poorly specified and implemented failure semantics. Prior implementations would capture a "failed" string, but not tell the task that the service returned a failure status.Task Parsers already accept stdout and stderr, and are the "final word" in resolving or rejecting Tasks.
v5.2.0provides a boolean to Parser's callable indicating if the wrapped service returned pass or fail, and the Parser may return a Promise now, as well.There's a new
SimpleParserimplementation you can use that fails ifstderris non-blank or a stream matched the.failpattern. -
🐞 initial
BatchProcessvalidation uses the newSimpleParserto verify the initialversionCommand. -
✨ child process pids are delivered to event listeners on spawn and close. See BatchClusterEmitter.
-
🐞 fix "Error: end() called when not idle" by debouncing stdout and stderr readers. Note that this adds latency to every task. See BatchProcessOptions's
streamFlushMillisoption, which defaults to 10 milliseconds. -
🐞 RegExp for pass and fail tokens handle newline edge cases now.
-
📦 re-added tslint and delinted code.
v5.1.0
- ✨
ChildProcessFactorysupports thunks that return either aChildProcessorPromise<ChildProcess> - 📦 Update deps
v5.0.1
- 📦 Update deps
- 📦 re-run prettier
v5.0.0
- 💔 The
rejectTaskOnStderrAPI, which was added in v4.1.0 and applied to all tasks for a givenBatchClusterinstance, proved to be a poor decision, and has been removed. TheParserAPI, which is task-specific, now receives both stdin and stderr streams. Parsers then have the necessary context to decide what to do on a per task or per task-type basis. - 🐞 In previous versions, batch processes were recycled if any task had any type of error. This version allows pids to live even if they emit data to stderr.
v4.3.0
- ✨ If your tasks return interim progress and you want to capture that data
as it happens, BatchCluster now emits
taskDataevents with the data and the current task (which may be undefined) as soon as the stream data is emitted. - 📦 Pulled in latest dependency versions
v4.2.0
- 📦 In the interests of less noise, the default logger is now the
NoLogger. Consumers may use theConsoleLoggeror anotherLoggerimplementation as they see fit.
v4.1.0
- ✨ Support for demoting task errors from
stderremissions:BatchProcess.rejectTaskOnStderris a per-task, per-error predicate which allows for a given error to be handled without always rejecting the task. This can be handy if the script you're wrapping (like ExifTool) writes non-fatal warnings to stderr. - ✨
BatchProcessOptions.passandBatchProcessOptions.failcan be RegExp instances now, if you have more exotic parsing needs.
v4.0.0
-
💔 Using Node 8+ to determine if a process is running with
kill(pid, 0)turns out to be unreliable (as it returns true even after the process exits). I tried to pull in the best-maintained "process-exists" external dependency, but that pulled in 15 more modules (this used to be a zero-deps module), and it was extremely unperformant on Windows.The TL;DR: is that
running(pid)now returns aPromise<boolean>, which had far-reaching signature changes to accomodate the new asynchronicity, hence the major version bump. -
💔 In an effort to reduce this library's complexity, I'm removing retry functionality. All parameters associated to retries are now gone.
-
✨ Internal state validation is now exposed by BatchCluster, and is used by tests to ensure no internal errors happen during integration tests. Previously these errors were simply logged.
v3.2.0
- 📦 New
Loggermethods,withLevels,withTimestamps, andfilterLevelswere shoved into a newLoggernamespace.
v3.1.0
- ✨ Added simple timestamp and levels logger prefixer for tests
- 🐞 Errors rethrown via BatchProcess now strip extraneous
Error:prefixes - 🐞 For a couple internal errors (versionCommend startup errors and internal
state inconsistencies on
onExitthat aren't fatal), we now log.errorrather than throw Error() or ignore.
v3.0.0
- ✨/💔
Taskpromises are only rejected withErrorinstances now. Note that also means thatBatchProcessObservertypes are more strict. It could be argued that this isn't an API breaking change as it only makes rejection values more strict, but people may need to change their error handling, so I'm bumping the major version to highlight that. Resolves #3. Thanks for the issue, Nils Knappmeier!
v2.2.0
- 🐞 Windows taskkill
/PIDoption seemed to work downcased, but the docs say to use uppercase, so I've updated it. - 📦 Upgrade all deps including TypeScript to 2.9
(v2.1.2 is the same contents, but np had a crashbug during publish)
v2.1.1
- 📦 More robust
endforBatchProcess, which may prevent very long-lived consumers from sporadically leaking child processes on Mac and linux. - 📦 Added Node 10 to the build matrix.
v2.1.0
- 📦 Introduced
Logger.traceand moved logging related to per-task items down totrace, as heavy load and large request or response payloads could overwhelm loggers. If you really want to see on-the-wire requests and results, enabletracein your debugger implementation. By default, theConsoleLoggeromits log messages with this level.
v2.0.0
- 💔 Replaced
BatchClusterObserverwith a simple EventEmitter API onBatchClusterto be more idiomatic with node's API - 💔 v1.11.0 added "process reuse" after errors, but that turned out to be
problematic in recovery, so that change was reverted (and with it, the
maxTaskErrorsPerProcessparameter was removed) - ✨
Rateis simpler and more accurate now.
v1.11.0
- ✨ Added new
BatchClusterObserverfor error and lifecycle monitoring - 📦 Added a number of additional logging calls
v1.10.0
- 🐞 Explicitly use
timers.setInterval. May address this issue. Thanks for the PR, Tim Fish!
v1.9.1
- 📦 Changed
BatchProcess.end()to useuntil()rather thanPromise.race, and always usekill(pid, forced)after waiting the shutdown grace period to prevent child process leaks.
v1.9.0
- ✨ New
Logger.setLogger()for debug, info, warning, and errors.debugandinfodefaults to Node's debuglog,warnanderrordefault toconsole.warnandconsole.error, respectively. - 📦 docs generated by typedoc
- 📦 Upgraded dependencies (including TypeScript 2.7, which has more strict verifications)
- 📦 Removed tslint, as
tscprovides good lint coverage now - 📦 The code is now prettier
- 🐞
delaynow allows unrefing the timer, which, in certain circumstances, could prevent node processes from exiting gracefully until their timeouts expired
v1.8.0
- ✨ onIdle now runs as many tasks as it can, rather than just one. This should provide higher throughput.
- 🐞 Removed stderr emit on race condition between onIdle and execTask. The error condition was already handled appropriately--no need to console.error.
v1.7.0
- 📦 Exported
kill()andrunning()fromBatchProcess
v1.6.1
- 📦 De-flaked some tests on mac, and added Node 8 to the build matrix.
v1.6.0
- ✨ Processes are forcefully shut down with
taskkillon windows andkill -9on other unix-like platforms if they don't terminate after sending theexitCommand, closingstdin, and sending the proc aSIGTERM. Added a test harness to exercise. - 📦 Upgrade to TypeScript 2.6.1
- 🐞
mochatests don't require the--exithack anymore 🎉
v1.5.0
- ✨
.running()works correctly for PIDs with different owners now. - 📦
yarn upgrade --latest
v1.4.2
- 📦 Ran code through
prettierand delinted - 📦 Massaged test assertions to pass through slower CI systems
v1.4.1
- 📦 Replaced an errant
console.logwith a call tolog.
v1.4.0
- 🐞 Discovered
maxProcswasn't always utilized byonIdle, which meant in certain circumstances, only 1 child process would be servicing pending requests. Added breaking tests and fixed impl.
v1.3.0
- 📦 Added tests to verify that the
kill(0)calls to verify the child processes are still running work across different node version and OSes - 📦 Removed unused methods in
BatchProcess(whose API should not be accessed directly by consumers, so the major version remains at 1) - 📦 Switched to yarn and upgraded dependencies
v1.2.0
- ✨ Added a configurable cleanup signal to ensure child processes shut down on
.end() - 📦 Moved child process management from
BatchClustertoBatchProcess - ✨ More test coverage around batch process concurrency, reuse, flaky task retries, and proper process shutdown
v1.1.0
- ✨
BatchClusternow has a force-shutdownexithandler to accompany the graceful-shutdownbeforeExithandler. For reference, from the Node docs:
The 'beforeExit' event is not emitted for conditions causing explicit termination, such as calling process.exit() or uncaught exceptions.
- ✨ Remove
Rate's time decay in the interests of simplicity
v1.0.0
- ✨ Integration tests now throw deterministically random errors to simulate flaky child procs, and ensure retries and disaster recovery work as expected.
- ✨ If the
processFactoryorversionCommandfails more often than a given rate,BatchClusterwill shut down and raise exceptions to subsequentenqueueTaskcallers, rather than try forever to spin up processes that are most likely misconfigured. - ✨ Given the proliferation of construction options, those options are now sanity-checked at construction time, and an error will be raised whose message contains all incorrect option values.
v0.0.2
- ✨ Added support and explicit tests for CR LF, CR, and LF encoded streams from spawned processes
- ✨ child processes are ended after
maxProcAgeMillis, and restarted as needed - 🐞
BatchClusternow practices good listener hygene forprocess.beforeExit
v0.0.1
- ✨ Extracted implementation and tests from exiftool-vendored