Code Monkey home page Code Monkey logo

express-cluster's Introduction

express-cluster

Run an express server on multiple processes. This is meant to be dropped in directly to your main entry point without having to setup a separate script that manages workers.

This works with any EventListener that emits the "close" event and has a close() method. If it's a server object (e.g. an express app, net.Server or http.Server, ensure that you've invoked listen before returning it).

By default the module will spawn os.cpus().length workers. You should configure this parameter for your workloads. You should pick the right number for your server based on testing.

Synopsis

var express = require('express');
var cluster = require('express-cluster');

cluster(function(worker) {
    var app = express();
    app.get('/', function(req, res) {
        res.send('hello from worker #' + worker.id);
    });
    return app.listen(0xbeef);
}, {count: 5})

API

express-cluster exports itself as a function that accepts config and workerFunctions as arguments. These can be provided in either order: cluster(config, workerFunction) or cluster(workerFunction, config).

Once node executes cluster() the current process will be forked the specified number of times. You should guard any code that should only be run in the master behind a check of process.env.NODE_UNIQUE_ID or a call to node's cluster.isMaster

workerFunction

This function is passed a worker object. See the node documentation for Worker for details.

config

This object should contain zero or more of these keys. Any other key/values are ignored.

{
    count: 5,       // number of workers: defaults to os.cpus().length
    respawn: true,  // respawn process on exit: defaults to true
    verbose: false, // log what happens to console: defaults to false

    // Attach the given function to each spawned worker. The function will
    // be bound to the worker that sent the message so you can setup a two
    // way message bus if you please. See examples/messaging.js for an
    // example.
    workerListener: function(){},

    // When in verbose mode, use a following writable stream (supports
    // the write function) instead of the default console
    outputStream: writableStream
}

express-cluster's People

Contributors

danhbear avatar dcreemer avatar eden avatar gonenduk avatar lrdcasimir avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

express-cluster's Issues

exiting worker: support showing signal that killed it

Hello,

I was looking over the source again and I noticed this line:

https://github.com/Flipboard/express-cluster/blob/master/src/index.coffee#L26

From how the documentation reads, it sounds like signal is sometimes available (if the worker was actually killed by a signal) - while the exit code is always available: https://nodejs.org/api/cluster.html#cluster_event_exit_1

I wound up writing it like this in my project, I thought it might be of use to you:

https://github.com/blitmap/coffeescript-snippets/blob/master/script-server.coffee#L34

why express-cluster run this 'console' out of cluster() many times?

var cluster = require('express-cluster');
console.log(1); // This code run at first, then it run another four times.(my computer have 4 cpus)
cluster(function() {
    var app = require('../app');
    app.set('port', process.env.PORT || 3000);
    var server = app.listen(app.get('port'), function() {
        log.info('Express server listening on port ', server.address().port, " with pid ", process.pid );
    });
});

remove dependency on http

Hello again :-)

I notice you are require()'ing the 'http' module in index.coffee but it is not used

no real harm done, http is of course a core module so it's available anyway - but please do remove :3

worker.process.pid isn't available in exit handler

Hello,

I noticed this line:

https://github.com/Flipboard/express-cluster/blob/master/src/index.coffee#L26

When testing this myself it caused an error - the worker object in the exit handler is actually null. It seems like the worker object is already destroyed/collected by the time the exit handler gets it.

What I did in mine was to save the worker process id when I attach the exit handler (yay closures!):

https://github.com/blitmap/coffeescript-snippets/blob/master/script-server.coffee#L31-L34

Also I wanted to point out 2 other things:

  1. https://github.com/Flipboard/express-cluster/blob/master/src/index.coffee#L9
  • I believe this should be config.count or ....
  • Also the parseInt() can return NaN. if you don't want to handle NaN you could just do +process.env.WORKER_COUNT to mean essentially the same thing (currently you support negative worker counts). The funny part is, if process.env.WORKER_COUNT is undefined +undefined is still NaN. NaN is still "falsey" so no problem. + would just be more concise to say the same thing, but parseInt() supports interpreting scientific notation.
  1. https://github.com/Flipboard/express-cluster/blob/master/src/index.coffee#L18
  • you can write: 0 ... workerCount here. .. is exclusive, ... is inclusive (<3 coffeescript)

I love how you handle SIGQUIT in the master - your exit is much more graceful than mine <3

(sorry for submitting so many issues, I tend to get carried away ~)

Allow to choose an output stream

In verbose mode, instead of writing to console.log please write to a stream.
The stream can be given in the options and can default to stdout

This will allow to use verbose mode and get the text notifications in the app log (for example, when using Winston logger).

writing to a stream is as easy as:
stream.write(message, encoding); //encoding is optional

process.send is not a function

/Users/xuxuewen/svn/niu_front/trunk/com.9niu.activity/node_modules/log4js/lib/appenders/clustered.js:120
process.send({ type: '::log-message', event: serializeLoggingEvent(loggingEvent)});
^

TypeError: process.send is not a function

reverse the arg list for cluster()

I see that you wrote express-cluster in Coffeescript - you distribute the compiled JS. I think calling cluster() would look nicer for people using Coffeescript if you reversed the arg list:

cluster { count: require('os').cpus().length + 1, respawn: true }, (worker) ->
  app = express()
  app.get '/', (req, res) -> res.send "Hello from worker ##{workder.id}!"
  app.listen 0xbeef

What do you think? :-)

session not saved

 app.use(function (req, res, next) {

                req.session.name="a1";
                if(req.session.name=="a1"){
                    console.log("a1");
                    req.session.name="a2";
                }else{
                    console.log("a2")
                }

            });

//return
a1
a1
a1
a1
a1
a1,...

cluster.isMaster is undefined

Hi,

I am having trouble with executing code in master pid:

const cluster = require('express-cluster');
if (cluster.isMaster) {
console.log('xx');
}
cluster(
worker => {
...

cluster.isMaster is undefined in my example code. What am I doing wrong?

Thanks,
Amadeus

increase default worker count by 1

Hello hello - I see that in express-cluster if process.env.WORKER_COUNT is not defined it assumes the number of workers should be: os.cpus().length

I am used to seeing: os.cpus().length + 1

I'm not exactly sure why this is. I've been told that on a dual-core processor without hyperthreading (2 execution threads) it is ideal to have 3 workers so the application appropriately saturates the scheduler. This doesn't really make sense to me, but it sounds like a poor mans' way of controlling thread/process affinity. I guess the idea is to make sure the clustered app as a whole stays responsive enough as a worker count equal to the number of cores is moderately starved by the rest of the system (other processes) being scheduled across the CPU.

The most correct answer is to probably measure and adjust as needed and just set WORKER_COUNT.

Anyway, I'm filing this because I just thought os.cpus().length + 1 was the more traditional default. I leave it up to you, of course :-)

Master

how judge Master process

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.