
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
cluster-service
Advanced tools
Turns your single process code into a fault-resilient multi-process service with built-in REST & CLI support
npm install cluster-service
https://npmjs.org/package/cluster-service
The short answer:
Turns your single process code into a fault-resilient multi-process service with
built-in REST & CLI support.
The long answer:
Adds the ability to execute worker processes over N cores for extra service resilience,
includes worker process monitoring and restart on failure, continuous deployment,
as well as HTTP & command-line interfaces for health checks, cluster commands,
and custom service commands.
Presentation:
http://x.co/bpnode
Stability:
With the v0.5 release we're effectively at an "Alpha" stage, with some semblance
of interface stability. Any breaking changes from now on should be handled gracefully
with either a deprecation schedule, or documented as a breaking change if necessary.
Turning your single process node app/service into a fault-resilient multi-process service with all of the bells and whistles has never been easier!
Your existing application, be it console app or service of some kind:
// server.js
console.log("Hello World");
Leveraging cluster-service
without adding a line of code:
npm install -g cluster-service
cservice "server.js" --accessKey "lksjdf982734"
This can be done without a global install as well, by updating your package.json
:
"scripts": {
"start": "cservice server.js --accessKey lksjdf982734"
},
"dependencies": {
"cluster-service": ">=0.5.0"
}
Now we can leverage npm
to find our local install of cluster-service
:
npm start
Or, if you prefer to control cluster-service
within your code:
// server.js
require("cluster-service").start({ workers: "./worker.js", accessKey: "lksjdf982734" });
// worker.js
console.log("Hello World"); // notice we moved our original app logic to the worker
Now that your service is resilient to worker failure, and utilizing all cores of your machine, lets talk to it. With your service running, type into the command-line:
restart all
or for a full list of commands...
help
or for help on a specific command:
help {command}
We can also issue commands from a seperate process, or even a remote machine (assuming proper access):
npm install -g cluster-service
cservice "restart all" --accessKey "my_access_key"
You can even pipe raw JSON, which can be processed by the caller:
cservice "restart all" --accessKey "my_access_key" --json
Check out Cluster Commands for more details.
When initializing your service, you have a number of options available:
cservice "config.json"
Or within your node app:
// server.js
// inline options
require("cluster-service").start({ workers: "worker.js", accessKey: "123" });
// or via config
require("cluster-service").start({ config: "config.json" });
workerCount
. An object indicates one or more worker objects:
{ "worker1": { worker: "worker1.js", cwd: process.cwd(), count: 2, ready: true, restart: true } }
.
This option is automatically set if run via command-line cservice "worker.js"
if
the .js
extension is detected.cservice "config.json"
if
the .json
extension is detected.cservice "restart all"
and no extension is detected.run
, will only output the result in JSON for
consumption from other tasks/services. No other data will be output.A DPS Cluster Service has two interfaces, the console (stdio), and an HTTP REST API. The two interfaces are treated identical, as console input/output is piped over the REST API. The reason for the piping is that a DPS Cluster Service is intentionally designed to only support one instance of the given service running at any one time, and the port binding is the resource constraint. This allows secondary services to act as console-only interfaces as they pipe all input/output over HTTP to the already running service that owns the port. This flow enables the CLI to background processes. The REST API is locked to a "accessKey" expected in the query string. The console automatically passes this key to the REST API, but for external REST API access, the key will need to be known.
{ host: "localhost", port: 11987, accessKey: "lksjdf982734" }
Invoking the REST interface directly would look something like:
curl -d "" "http://localhost:11987/cli?cmd=help&accessKey=lksjdf982734"
Or better yet, use the run
option to do the work for you:
cservice "help" --accessKey "lksjdf982734"
// same as
cservice --run "help" --accessKey "lksjdf982734"
While a Cluster Service may provide its own custom commands, below are provided out-of-the-box. Commands may be disabled by overriding them.
Creating custom, or overriding commands and events is as simple as:
var cservice = require("cluster-service");
cservice.on("custom", function(evt, cb, arg1, arg2) { // "custom" command
// can also fire custom events
cservice.trigger("on.custom.complete", 1, 2, 3);
};
cservice.on("test", function(evt, cb, testScript, timeout) { // we're overriding the "test" command
// arguments
// do something, no callback required (events may optionally be triggered)
};
// can also issue commands programatically
cservice.trigger("custom", function(err) { /* my callback */ }, "arg1value", "arg2value");
Events are emitted to interested parties.
By default, when a process is started successfully without it exiting, it is assumed to be "running". This behavior is not always desired however, and may optionally be controlled by:
Indicate the worker is NOT ready, via ready
option:
require("cluster-service").start({ workers: { "async": { worker: "async_worker.js", ready: false } } });
Have the worker inform the master once it is actually ready:
// worker.js
setTimeout(funtion() {
// dumb example of async support
require("cluster-service").workerReady(); // we're ready!
});
Additionally, a worker may optionally perform cleanup tasks prior to exit, via:
// worker.js
require("cluster-service").workerReady({
onWorkerStop: function() { /* lets clean this place up */ }
});
Commands may be granted "inproc" (no trust), "local" (low trust), or "remote" (default). Setting access control at compile time can be done within the command, like so:
// exit.js
module.exports.control = function(){
return "local";
};
Or may be overriden at runtime via:
// server.js
require("cluster-service").control({ "exit": "local" });
Combining the Worker Process (Cluster) model with a CLI piped REST API enables the ability to command the already-running service to replace existing workers with workers in a different location. This capability is still a work in progress, but initial tests are promising.
Cluster Service A1 starts
N child worker processes started
Cluster Service A2 starts
A2 pipes CLI to A1
A2 issues "upgrade" command
A1 spins up A2 worker
New worker is monitored for N seconds for failure, and cancels upgrade if failure occurs
Remaining N workers are replaced, one by one, until all are running A2 workers
Upgrade reports success
Download and install:
git clone https://github.com/godaddy/node-cluster-service.git
cd node-cluster-service
npm install
Now test:
npm test
View code coverage in any browser:
coverage/lcov-report/index.html
FAQs
Turns your single process code into a fault-resilient multi-process service with built-in REST & CLI support
The npm package cluster-service receives a total of 1,673 weekly downloads. As such, cluster-service popularity was classified as popular.
We found that cluster-service demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.