Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

cluster2

Package Overview
Dependencies
Maintainers
1
Versions
70
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cluster2 - npm Package Compare versions

Comparing version 0.2.5 to 0.3.0

2

examples/express/express-server.js

@@ -41,2 +41,4 @@ /*

ecv: {
path: '/ecv', // Send GET to this for a heartbeat
control: true, // send POST to /ecv/disable to disable the heartbeat, and to /ecv/enable to enable again
monitor: '/',

@@ -43,0 +45,0 @@ validator: function() {

3

examples/http-server-mult-ports.js

@@ -40,4 +40,3 @@ /*

port: [3000, 3003],
cluster: true,
ecv: false
cluster: true
});

@@ -44,0 +43,0 @@ c.on('died', function(pid) {

@@ -40,4 +40,3 @@ /*

port: 3000,
cluster: true,
ecv: false
cluster: true
});

@@ -44,0 +43,0 @@ c.on('died', function(pid) {

@@ -28,11 +28,21 @@ /*

exports.enable = function(app, port, path, monitor, validator) {
app.get(path || '/ecv', function(req, res) {
exports.enable = function(app, options, emitter, validator) {
var path = options.ecv.ecvPath || '/ecv';
var monitor = options.ecv.monitor || undefined;
var control = options.ecv.control || false;
var root = path || '/ecv';
var disabled;
app.get(root, function(req, res) {
var tosend = {
date : new Date ,
port : port
port : options.port
};
var options = options || {
if(disabled) {
// Drop the ball
away(req, res, tosend);
return;
}
var coptions = {
host: 'localhost',
port: port,
port: options.port,
path: monitor || '/',

@@ -44,6 +54,5 @@ method: 'GET',

accept: 'application/json'
}
};
var creq = http.request(options, function(cres) {
var creq = http.request(coptions, function(cres) {
cres.setEncoding('utf8');

@@ -79,2 +88,43 @@ var data = '';

});
if(control === true) {
app.post(root + '/disable', function (req, res) {
disabled = true;
emitter.emit('warning', {
message: 'Disable request received'
});
if(process.send) {
process.send({
command: 'disable'
});
}
res.writeHead(204, {
'since': new Date(Date.now() - process.uptime()*1000),
'cache-control': 'no-cache',
'X-Powered-By': 'Cluster2',
'Connection': 'close'
});
res.end()
});
app.post(root + '/enable', function (req, res) {
disabled = false;
emitter.emit('warning', {
message: 'Enable request received'
});
if(process.send) {
process.send({
command: 'enable'
});
}
res.writeHead(204);
res.end()
});
process.on('message', function (message) {
if(message && message.command) {
disabled = message.command === 'disable';
}
});
}
};

@@ -86,3 +136,5 @@

'since': new Date(Date.now() - process.uptime()*1000),
'cache-control': 'no-cache'
'cache-control': 'no-cache',
'X-Powered-By': 'Cluster2',
'Connection': 'close'
});

@@ -97,3 +149,5 @@ res.write('status=AVAILABLE&ServeTraffic=true&ip='+ req.connection.address()['address'] +'&hostname='+ hostname +'&port=' + tosend.port+ '&time=' + tosend.date.toString());

'since': new Date(Date.now() - process.uptime()*1000),
'cache-control': 'no-cache'
'cache-control': 'no-cache',
'X-Powered-By': 'Cluster2',
'Connection': 'close'
});

@@ -103,1 +157,13 @@ res.write('status=WARNING&ServeTraffic=false&ip='+ req.connection.address()['address'] +'&hostname='+ hostname +'&port=' + tosend.port + '&time=' + tosend.date.toString());

}
function away(req, res, tosend) {
res.writeHead(400, {
'content-type': 'text/plain',
'since': new Date(Date.now() - process.uptime()*1000),
'cache-control': 'no-cache',
'X-Powered-By': 'Cluster2',
'Connection': 'close'
});
res.write('status=DISABLED&ServeTraffic=false&ip='+ req.connection.address()['address'] +'&hostname='+ hostname +'&port=' + tosend.port + '&time=' + tosend.date.toString());
res.end();
}

@@ -43,3 +43,5 @@ /*

this.options.monPort = this.options.monPort || 3001;
this.options.ecvPath = this.options.ecvPath || '/ecv';
this.options.ecv = this.options.ecv || {
path: '/ecv'
}
this.options.monPath = this.options.monPath || '/';

@@ -66,3 +68,2 @@ this.options.noWorkers = this.options.noWorkers || os.cpus().length;

ecv: self.options.ecv,
ecvPath: self.options.ecvPath || '/ecv',
noWorkers: self.options.noWorkers,

@@ -84,3 +85,3 @@ timeout: self.options.timeout || 30 * 1000, // idle socket timeout

if(self.options.ecv) {
ecv.enable(app, self.options.port, self.options.ecvPath, self.options.ecv.monitor, function (data) {
ecv.enable(app, self.options, self, function (data) {
return true;

@@ -100,3 +101,3 @@ });

if(self.options.ecv) {
ecv.enable(app, self.options.port, self.options.ecvPath, self.options.ecv.monitor, function (data) {
ecv.enable(app, self.options, self, function (data) {
return true;

@@ -103,0 +104,0 @@ });

@@ -146,3 +146,17 @@ /*

this.stats.noWorkers++;
worker.on('message', function(message) {
if(message && message.command) {
self.notifyWorkers(message);
}
});
return worker;
}
this.notifyWorkers = function(message) {
_.each(self.workers, function(worker) {
worker.send(message)
});
}
}

@@ -157,4 +171,5 @@

this.stats.freemem = os.freemem();
this.workers = [];
// Monitor to server ecv checks
// Monitor to serve log files and other stats - typically on an internal port
var monitor = new Monitor({

@@ -174,3 +189,4 @@ stats: self.stats,

for(var i = 0; i < self.options.noWorkers; i++) {
self.createWorker();
var worker = self.createWorker();
self.workers[worker.pid + ''] = worker;
}

@@ -182,3 +198,5 @@

self.stats.noWorkers--;
self.createWorker();
var worker = self.createWorker();
self.workers[worker.pid + ''] = worker;
delete self.workers[worker.pid + ''];
delete self.stats.workers[worker.pid];

@@ -258,3 +276,3 @@ };

if(self.options.ecv) {
ecv.enable(app, port, self.options.ecvPath, self.options.ecv.monitor, function(data) {
ecv.enable(app, self.options, self.emitter, function(data) {
return true;

@@ -261,0 +279,0 @@ });

@@ -8,3 +8,3 @@ {

"name": "cluster2",
"version": "0.2.5",
"version": "0.3.0",
"repository": {

@@ -11,0 +11,0 @@ "type": "git",

@@ -17,2 +17,4 @@ ## What is cluster2

* Events for logging cluster activities
* Exit with error code when the port is busy to fail start scripts
* Disable monitor
* and more coming soon

@@ -97,4 +99,8 @@

view application logs (whatever is written to a `/logs` dir), and npm dependencies.
* `ecv`: A validator to validate the runtime health of the app. If found unhealthy, emits a disable
traffic signal at path `/ecv`. ECV stands for "extended content verification".
* `ecv`: ECV stands for "extended content verification". This is an object with the following
additional properties:
* `path`: A path to serve a heart beat. See below.
* `monitor`: A URI to check before emitting a valid heart beat signal
* `control`: When true, allows clients to enable or disable the signal. See below.
validator to validate the runtime health of the app. If found unhealthy, emits a disable
* `noWorkers`: Defaults to `os.cpus().length`.

@@ -132,11 +138,5 @@ * `timeout`: Idle socket timeout. Automatically ends incoming sockets if found idle for this

<<<<<<< HEAD
Completion of `shutdown()` does not necessarily mean that all worker processes are dead immediately. The workers
may take a while to complete processing of current requests and exit. The `shutdown` flow only
guarantees that the server takes no new connections.
=======
Completion of `shutdown()` does not necessarily mean that all worker processes are dead immediately.
The workers may take a while to complete processing of current requests and exit. The `shutdown()`
flow only guarantees that the server takes no new connections.
>>>>>>> 70b11cd6a93ae49ff959e60d52a5ba91b012690f

@@ -184,1 +184,56 @@ ## Cluster2 Events

## Routing Traffic
It is fairly common for proxies or load balancers deployed in front of node clusters, and those
proxies to use monitor URLs to detect the health of the cluster. Cluster2 includes a monitor
at `http://<host>:<port>/ecv`. You can change this by setting the `path` property when initializing
the cluster.
In case you want to take the node cluster out of rotation from the proxy/load balancer, you can do
so by setting `control` to `true` when initializing the cluster. At runtime, you can send a `POST`
request to `http://<host>:<port>/ecv/disable`. Once this is done, further requests to
`http://<host>:<port>/ecv` will get a network error. You can bring the cluster back to rotation by
sending a `POST` request to `http://<host>:<port>/ecv/enable`.
Since it will be potentially disastrous to let artibrary clients enable/disable traffic, you should
configure your proxy/load balancer to prevent external traffic to `/ecv*`.
To test this, bring up an example
node examples/express/express-server.js
and send a `GET` request to `http://localhost:3000/ecv` and notice the response.
HTTP/1.1 200 OK
X-Powered-By: Cluster2
content-type: text/plain
since: Fri May 18 2012 09:49:32 GMT-0700 (PDT)
cache-control: no-cache
Connection: keep-alive
Transfer-Encoding: chunked
status=AVAILABLE&ServeTraffic=true&ip=127.0.0.1&hostname=somehost&port=3000&time=Fri May 18 2012 09:49:49 GMT-0700 (PDT)
To flip the monitor into a disabled state, send a `POST` request to `http://localhost:3000/disable`.
HTTP/1.1 204 No Content
X-Powered-By: Cluster2
since: Fri May 18 2012 09:54:25 GMT-0700 (PDT)
cache-control: no-cache
Connection: close
Subsequent `GET` requests to `http://localhost:3000/ecv` will return a response similar to the one
below.
HTTP/1.1 400 Bad Request
X-Powered-By: Cluster2
content-type: text/plain
since: Fri May 18 2012 09:54:25 GMT-0700 (PDT)
cache-control: no-cache
Connection: close
Transfer-Encoding: chunked
status=DISABLED&ServeTraffic=false&ip=127.0.0.1&hostname=somehost&port=3000&time=Fri May 18 2012 09:55:17 GMT-0700 (PDT)
To flip the monitor back into an enabled state, send a `POST` request to `http://localhost:3000/enable`.

@@ -18,6 +18,6 @@ * <del>Basic cluster</del>

* ws connection causing workers to live
* Check for open port and and exit when busy with an error exit code
* <del>Check for open port and and exit when busy with an error exit code</del>
* Write start/shutdown/stop to log
* Send counters in bulk
* Traffic in and out - continue connection listening but update ecv
* <del>Traffic in and out - continue connection listening but update ecv</del>
* Raise heartbeats thru logEmitter
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc