@darkobits/sentinelle
v0.6.11
Published
File watcher / process manager.
Downloads
27
Readme
A development tool used to run a process (re: file) and restart it when nearby files change.
Contents
Install
In most cases, Sentinelle should be installed as a development dependency in your project:
$ npm i -D @darkobits/sentinelle
If you wish to install Sentinelle globally on your system:
$ npm i -g @darkobits/sentinelle
Use
Sentinelle consists of a CLI (sentinelle
) and a Node API. Most users will find it more convenient to
use the CLI.
CLI
The Sentinelle CLI expects a single positional argument which should be the path to your application's entrypoint:
$ sentinelle ./server.js
If you need to pass arguments to your entrypoint, this argument should be wrapped in quotation marks:
$ sentinelle "./server.js --port=8080"
Sentinelle also accepts the following named arguments, which may be set via command-line flags or via a configuration file, which may be any of the following:
| Name | Format |
|------------------------|------------|
| .sentinelle.json
| JSON |
| .sentinelle.yml
| YAML |
| sentinelle.config.js
| JavaScript |
--bin
By default, Sentinelle assumes that your project's entrypoint has executable permissions and contains a shebang. Using this idiomatic approach, Sentinelle does not need to know about the runtime required to execute your project. However, if your environment does not support shebangs, or if you need to pass arguments to the runtime, use this option to do so.
For example, if we needed to run our Node app server.js
with the --inspect
flag:
$ sentinelle --bin="node --inspect" ./server.js
Or, if we are working on a Python project:
$ sentinelle --bin="python -m" ./server.py
To conveniently set this option via a configuration file (YML in this case):
.sentinelle.yml
bin: python
--watch
By default, Sentinelle always watches the directory containing the entrypoint file, its peers, and any of their children. However, if you need to watch additional directories or files, you may use this argument.
$ sentinelle --watch ../other-file.js --watch ../other-directory ./server.js
--kill
Default: SIGINT
Instructs Sentinelle to use a different signal when restarting your application. By default, processes
will receive the SIGINT
signal when Sentinelle needs them to shut-down due to a file change or because
the user issued an explicit SIGINT
(via CTRL+C, for example).
--quiet
Default: false
Suppress all log messages from Sentinelle except warnings and errors.
Node API
Sentinelle's default export is a factory function that accepts a single options object and returns an object with several methods.
The following options are supported:
entry
This option is required.
Type: string
Path to the entrypoint file Sentinelle will run, as well as any additional arguments to pass to it.
bin
Type: string
If your entrypoint is not executable, you may explicitly specify a runtime (node
, python
, etc.) to
use to invoke entry
. This option may also contain any custom arguments you may need to pass to the
runtime itself. See above for explanation.
watch
Type: Array<string>
Additional files and/or directories to watch in addition to the directory containing entry
.
processShutdownGracePeriod
Type: string | number
Default: '4 seconds'
Amount of time Sentinelle will wait after issuing a kill signal before forcefully killing a process. If
a number is provided, it will be assumed to be the number of milliseconds to wait. If a string is
provided, it will be parsed using the ms
package. Therefore, strings
such as '5 seconds'
are valid.
processShutdownSignal
Type: string
Default: SIGINT
POSIX signal to send to a process to indicate that it needs to shut down.
stdio
Type: string | Array<string>
Default: ['inherit', 'inherit', 'pipe']
Input/output configuration for the spawned process.
The object returned has the following methods:
start()
Starts the process and initializes file watchers. Returns a Promise that resolves when this operation is complete.
restart(signal?: string)
Restarts the process. By default, the configured processShutdownSignal
is sent to the process.
However, this may be overridden by providing an optional signal
argument to this function. Returns a
Promise
that resolves when this operation is complete.
stop(signal?: string)
Stops the current process if one is running and closes all file watchers. By default, the configured
processShutdownSignal
is sent to the process. However, this may be overridden by providing an optional
signal
argument to this function. Returns a Promise that resolves when this operation is complete.
Node Debugger & I/O Configuration
The Node debugger can make Sentinelle's job harder than it otherwise would be. Nevertheless, debugging is a critical part of development, so Sentinelle tries to work around some of these quirks as best it can.
By default, standard input and standard output are set to inherit
, which results in the highest
quality output and best user experience. However, Sentinelle sets up standard error using pipe
. You
will still see output from standard error, but it may not have full color support.
Sentinelle then monitors standard error, which is where Node writes messages about debuggers, and keeps track of when debuggers connect and disconnect from the child process. By doing this, it can take appropriate action when one of the following scenarios occur:
Hanging Debugger: This happens when a process starts, a debugger attaches, then at some later point the process naturally exits and the debugger is not paused on any breakpoint. When this happens, Node will keep the process alive and write something like
Waiting for the debugger to disconnect...
to standard error. When Sentinelle detects this, it will force-kill the process so that it can cleanly re-start it on the next file change.Paused Debugger: This happens when a process such as a web-server (which keeps the JavaScript event loop running indefinitely) starts, a debugger attaches, pauses on a breakpoint or
debugger;
statement, and then Sentinelle detects a file change and now needs to shut-down and re-start the process. When this happens, Node will keep the process alive even if the process receives aSIGINT
. When Sentinelle detects this, it will wait for the configured grace period and then send aSIGKILL
to the process, which is the only signal that will actually cause Node to release the debugger and allow the process to exit. Note that because the debugger has paused execution, your process will not run any shutdown handlers, resulting in a potentially un-clean exit. To avoid this scenario, ensure execution is resumed before saving any files.
Debugging
Sentinelle respects the LOG_LEVEL
environment variable, which may be set to any valid NPM log level.
To produce additional output, you may set LOG_LEVEL
to verbose
or silly
:
LOG_LEVEL=silly sentinelle ./server.js