Giter Club home page Giter Club logo

up's Introduction

NOTE: up has been renamed in npm as "up-time" https://npmjs.org/package/up-time

Up

Zero-downtime reloads built on top of the distribute load balancer.

Simply running

$ up --port 80 --watch my-http-server.js

Will start my-http-server.js on port 80, then reload it with no downtime when files change in the working directory.

This project is deprecated!

Features

  • Works with Node 0.6+
  • Works at the HTTP request level. It never drops requests or destroys Keep-Alive sockets while reloading.
  • Compatible with any HTTP server.
  • Easy-to-use CLI interface for development with automatic reloading upon file changes.
  • Gracefully handles reloads with syntax errors during development.
  • Built on distribute.
  • Supports transpilers such as CoffeeScript.

Setup

Make sure you structure your code so that your http server lives in a separate module that can be required.

server.js

module.exports = http.Server(function (req, res) {
  res.writeHead(200);
  res.end('Hello World');
});

A) CLI

To get the up command, make sure to install with the -g flag:

$ npm install -g up

Usage: up [options]

The up command accepts the following options:

  • -p/--port

    • The port to listen on. Not required if the module already listens.
    • Defaults to 3000.
  • -w/--watch

    • Whether to watch for changes.
    • Watches the working directory for changes.
  • -r/--require <mod>

    • Specifies a module to require from each worker.
    • Can be used multiple times.
    • Tranpilers such as CoffeeScript can be supported with --require|-r coffee-script
  • -n/--number

    • Number of workers. It gets evaluated with eq.js.
    • You can optionally use the cpus variable. eg: cpus + 2.
    • You can use all the Math methods. eg: round(cpus / 2).
    • Defaults to number of CPUS, or 1 if NODE_ENV is development.
  • -t/--timeout

    • Number of ms after which a worker is killed once it becomes inactive.
    • Strings like '10s' are accepted.
    • Defaults to '10m', or '500ms' if NODE_ENV is development.
  • -k/--keepalive

    • start a new worker after one dies unexpectedly
  • -f/--pidfile

    • A filename to write the pid to
    • If specified, restarts can be achieved with: "kill -s SIGUSR2 cat pidfile.txt"
  • -T/--title

    • A value to give process.title.
    • Defaults to up.
    • The value will be appended with master or worker (e.g "up master", "up worker").

B) JavaScript API

var up = require('up')
  , master = http.Server().listen(3000)

// initialize up
var srv = up(master, __dirname + '/server');

process.on('SIGUSR2', function () {
  srv.reload();
});

require('up') exports the UpServer constructor, which takes three parameters:

  • server (http.Server) server to accept connections on
  • module (String) absolute path to the module.
  • options (Object)
    • numWorkers: (Number|String): see --workers above.
    • workerTimeout: (Number|String): see --timeout above.
    • title: (String): see --title above.
    • assumeReady: (Boolean): see Worker readiness below.
    • keepAlive: (Boolean): see --keepalive above.
    • minExpectedLifetime: (Number|String): Number of ms a worker is expected to live. Don't auto-respawn if a worker dies earlier. Strings like '10s' are accepted. Defaults to '20s'.

Middleware

An UpServer inherits from a Distributor, which means you can use() any distribute middleware.

The main difference is that the "default handler" of up (ie: the last function in the middleware chain) is the one that executes the round-robin load balancing.

Reloading

To reload the workers, call srv.reload(). In the example above and CLI, this is called by sending the SIGUSR2 signal:

$ kill -s SIGUSR2 <process id>

If you're running with up CLI, this command is output to stderr for your convenience.

The CLI tool also auto-reloads if you pass the --watch option and a file changes in the working directory.

Strategy

  1. An up server starts with an arbitrary number of workers, which defaults to the number of CPUs.
  2. When a reload instruction is received, it spawns an identical number of workers.
  3. Upon the first of those workers binding to a port, any subsequent requests are sent to that worker, and all the workers containing old code are discarded.
  4. The discarded workers could have been processing requests, so they only truly die after the configured workerTimeout, which defaults to 10 minutes in production. This means that if a user was uploading a file, his request will be processed without interruptions.
  5. As other workers bind and become available, they join the round-robin round.

Worker readiness

By default up assume that new workers are ready for new connections, immediately after they have been required. This can be changed by setting assumeReady to false, on the options object when initializing the up server through the JavaScript API.

The worker then needs to tell up, when it's ready, like this:

var up = require('up');
// Dummy async event
setTimeout(function(){
	up.ready();
}, 1000);

Credits

(The MIT License)

Copyright (c) 2011 Guillermo Rauch <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

up's People

Contributors

rauchg avatar mugami-ast avatar simonexmachina avatar speier avatar coreh avatar tootallnate avatar wvl avatar tj avatar brianloveswords avatar pharcosyle avatar mbrevoort avatar deltasquare4 avatar arlolra avatar jmreidy avatar nateps avatar sbader avatar

Stargazers

MeghanROk avatar _David_ avatar Ali Torki avatar Kimberly Thach [Ghostglass] avatar  avatar  avatar André Philip avatar Nitish Makhija avatar Sakol Assawasagool avatar Fady Samir avatar Mohamed A. Othman avatar Jaimy Emmanuel avatar Akshay Pratap Singh avatar Jonathan Kau avatar xiaomao Feng avatar Edward Chan Jia Wei avatar Alienware avatar Chris Witko avatar Theofanis Despoudis avatar kapil verma avatar Juri Grabowski avatar ASCE1885 avatar Philip Kazmeier avatar Ruibin avatar Vahagn Mkrtchyan avatar  avatar Martín García avatar NoScripter avatar bianl avatar Gavin Engel avatar  avatar Sam Vafaee avatar Fedor Korshunov avatar Angus H. avatar Mika avatar Victor Algaze avatar Curry avatar Michael Anthony avatar  avatar kelvin  knighton avatar Li Bin avatar Paulo McNally avatar Honam avatar Nguyen Duy avatar Dan Levy avatar jon ⚝ avatar Anderson Andrade avatar Marko Jankovic avatar TANG SHI QIANG avatar Eytan Biala avatar Jean-Baptiste Pionnier avatar Ryota Yoshikawa avatar  avatar avinash avatar Gui Lipan avatar Viktor Vasilev avatar Fatih Kaya avatar Abu Ashraf Masnun avatar Joe avatar Jeff Moore avatar Flo avatar Yue avatar Vishal Shah avatar mark prokoudine avatar ZeCheng Dai avatar Loty Gero avatar Ben Smith avatar Kelly Campbell avatar Yue Chen avatar Mateusz "Serafin" Gajewski avatar James R Qualls avatar Orr Siloni avatar Edgar de Oliveira Maciel avatar Hiroshi IKEGAMI avatar Sin V. avatar Kevin Whitman avatar Kalin Krustev avatar Teera Laiteerapong avatar Glavin Wiechert avatar Maciej Goszczycki avatar Jesse Yang avatar Lucas Pereira Brígida avatar Alex Grin avatar ᴘɪᴇʀᴄᴇ ᴍᴏᴏʀᴇ™ avatar  avatar  avatar Francisco Leite avatar Hiroaki Yamane avatar Yarek T avatar Andre Z. Sanchez avatar daylilyfield avatar Sebastian Henao avatar Christian Hochfilzer avatar Marcin Boćkowski avatar Steve Thomas avatar Eric Saboia avatar Reynaldo Tortoledo avatar Thomas White avatar ixaxaar avatar Craig McDonald avatar

Watchers

arden avatar  avatar Barry Abrahamson avatar Alex Vazquez avatar  avatar Damián Suárez avatar Laura Melo avatar Josh Taylor avatar André Philip avatar Christian Gastrell avatar Peter Kiss avatar tom zhou avatar Kate Ray avatar Christian Hochfilzer avatar Gustave Nganso avatar Ryan Yoon avatar Leonel Machava avatar James Cloos avatar hunslater avatar Stefano Gargiulo avatar Pierre avatar  avatar Juri Grabowski avatar Simeon Mugisha avatar Michael Anthony avatar Edgar de Oliveira Maciel avatar Ary Purnomoz avatar  avatar  avatar  avatar

up's Issues

Implement Worker interface

Expose:

  • Worker#port
  • Worker#load

Emit spawn when Worker#port is ready.
From main server listen on spawn to introduce worker to the round, terminate to remove it.

process.title on OSX

The assertion for process.title actually fails now in node-v0.8.x. Apparently since it OSX technically always ignored the setting, node does the same and no longer set its in memory either.

Not sure whats worse, axe the assertion or do some OS sniffing in the test lol?

Access to process.env

Hi, my server.js looks like this:

var http = require('http')
module.exports = http.Server(function (req, res) {
    res.writeHead(200);
    res.end('Hello World');
    console.log(process.env)
});

I start it using: $ up --watch --timeout 500ms server.js
But what I see in console is just: { NODE_CHANNEL_FD: '42' }

What is the proper way to access process.env ?

Up v0.2.2 on node v0.8.1

Is up ready for production ?

There is a weird problem with it when used with express.
In a nutshell when a route is created and then deleted sometimes it will
work and sometimes it wouldn't work, you load the page it works, you reload it doesn't
and on and on...

I thought it was chrome cache, i deleted all cache since the beginning of time and still the same thing.
when i kill up and attempt to run it again up -w -p 3000 app.js i would get address in use error,
for up to work again i need to killall node and then up runs.

Another problem is with up code reload, i have 20 node processes for a single app, is this normal ?

retain --flags

it seems that 'up' does not retain the node flag --harmony_proxies when respawning.
bug, feature, or I'm lost?

Add worker auto-respawning with max tries

  • Option to ensure that if a worker dies it tries to respawn immediately ?
  • Option to ensure number of active workers always stays at numWorkers or above ?
  • Option to ensure that there's always at least one worker alive and otherwise respawn ?
  • When respawning, if worker fails to listen within certain timeout, retry ?
  • Have a retry threshold to avoid overload ?
  • When respawning, if worker dies shortly after listening, consider it an unsuccessful respawn and try ? This means it would still be captured by the retry threshold and you can't get into an endless cycle of considering the worker spawned, then dying shortly after listening, then triggering reload, ad infinitum.

Discussion: should the master spawn a new worker if an exception kills one?

Is it/should it be one of the design goals of up to add a new worker to the pool if one dies unexpectedly?

A contrived example, but a server like the following can only survive N requests, where N is the initial number of spawned workers.

// server.js
function hdlr (request, response) {
  response.end(''+Math.random());
  process.nextTick(function () { crash(); })
}
module.exports = require('http').createServer(hdlr);

I think it'd be great if up could ensure that it never gets to a point where there are zero active workers. I've been experimenting with using up in a semi-production environment and I've been burnt by this before, but I wanted to make sure this wasn't a WONTFIX type of issue before putting any time into patching it.

UpServer tries to reload twice in a row and fails

The command line I use was:
node node_modules/up/bin/up -p 9400 -w server

After I touched a file, the following happens:

  up-cli /home/accerqueira/experiments/server/server.js change detected - reloading
  up reloading - spawning 2 new workers
  up spawning 2 workers from master 8738
  up worker 8745 created
  up worker 8746 created
  up-cli /home/accerqueira/experiments/server/server.js change detected - reloading
  up killing spawning worker 8745

/home/accerqueira/experiments/server/node_modules/up/lib/up.js:127
    this.spawning[i].shutdown();
                     ^
TypeError: Cannot call method 'shutdown' of undefined
    at UpServer.reload (/home/accerqueira/experiments/gg-web/node_modules/up/lib/up.js:127:22)
    at /home/accerqueira/experiments/gg-web/node_modules/up/bin/up:288:9
    at FSWatcher.<anonymous> (/home/accerqueira/experiments/gg-web/node_modules/up/bin/up:275:9)
    at FSWatcher.emit (events.js:70:17)
    at FSEvent.onchange (fs.js:665:12)

I'm using 15e82c6, traced the error back to dc4e57e, when it was working, but I could fix by reverting 2 lines from 6ad3f6b.

"depreciated" -> what to?

Is there a better alternative, now that this project has been depreciated?

I'm running a simple node server (faye) and I'd like to have it be able to handle graceful restarts

Using with coffee

Not sure i understand how to use up with a .coffee file. I tried using up -r coffee-script server.coffee but get the same error as if I ran node server.coffee

Fails to start in background

If I execute the following using up -n 1 test.js (in the foreground) it behaves as expected, but if I start this in the background using up -n 1 test.js & then the master dies, the workers never output 'started' or 'listening' and eventually commit suicide.

console.log('started');
module.exports = server = require('express').createServer();
server.on('listening', function() {
  console.log('listening');
});

CoffeeScript support

I'd like to be able to specify a .coffee file on the command line. Obviously I can fork and do this myself, but has anyone else done this?

Do not use up with node v0.10.0 (v0.10+?)

If up becomes saturated with (very) minimal traffic, the server will become unresponsive to requests and memory usage will skyrocket along with CPU.

I only tested locally, so it's possible it might just be me, but I doubt it.

You may see this message:

(libuv) Failed to create kqueue (24)

index.js

process.title = 'up-test';

var up = require('up')
    , server = require('http').Server().listen(3100);

var srv = up(server, __dirname + '/blah.js', {
        numWorkers: 4
});

blah.js

process.title = 'up-test-worker';

var http = require('http');

module.exports = http.Server(function (req, res) {
  res.writeHead(200);
  res.end('Hello World');
  console.log('connection...' + new Date());
});

setInterval(function() { console.log(process.pid + ' waiting for conntections...'); }, 5000);

Use apache's benchmarking tool:

ab -n16 -c8 http://localhost:3100/

c can be anything > numWorkers
n should be anything > c

On rare occasions, the above command will succeed without causing errors. Might want to try higher numbers.

I didn't investigate too deeply beyond "oh... up is broken", but I think it has something to do with this: http://stackoverflow.com/a/15537504/670023

I think this was discussed in #62, but I wanted to make something more prominent and supply a test.

Not gracefull

This module do not restart workers gracefull, it just stop the event loop. Any clients there was about to receive would be destroyed.

A better alternativ is to do server.close() and proces._channel.close() and perhaps disconnect any clients after an optional timeout.

Implement a proper shutdown()/close() function

When using the up API with process management tools like upstart on Ubuntu there is no clean way to stop the up server cleanly: it should provide a close() or shutdown() function that closes all network ports, shuts down all workers (and their associated processes) and exits completely. Right now I've had to jury-rig a process.exit(0) whenever upstart sends it a TERM signal, but it should tidy up behind itself.

X-Forwarded-Proto set to 'httpshttps' (bug in node-http-proxy)

For the record: http-party/node-http-proxy#266 affects distribute, and thus it affects up. The outcome is that behind a reverse proxy that terminates ssl, the header X-Forwarded-Proto is set to "httpshttps", which can give weird results, ie. (express req.protocol).

As soon as nodejitsu releases a fixed package, someone should update distrubute's dependencies and the ones of up.
Or reference a fork in the meantime.

CLI doesn't work with ExpressJS servers

The CLI does an instanceof http.Server check which fails for Express servers, even though they do inherit from http.Server. Using the JavaScript interface for up works just fine, but since the JS interface doesn't support --watch it doesn't help me any. :(

Fails when starting using upstart

When I start up manually, it works perfect. When I try to start with with upstart it fails with the following output:

up-cli starting cluster with 1 workers on port 3000
  up-cli `�[97mkill -s SIGUSR2 864�[90m` or �[97mctrl + r�[90m to load new code
  up spawning 1 workers from master 864
  up worker 867 created
AssertionError: stdin must be initialized before calling setRawMode
    at Object.setRawMode (tty.js:37:10)
    at Object.<anonymous> (/usr/local/lib/node_modules/up/bin/up:164:5)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:31)
    at Function._load (module.js:308:12)
    at Array.0 (module.js:479:10)
    at EventEmitter._tickCallback (node.js:192:40)

And here is my upstart script:

start on startup
stop on shutdown

script
    exec /usr/local/bin/up /home/jack/web/app.js >> /var/log/up.log 2>&1
end script

Project Abandoned?

Is this project still active? If not, is someone willing to fork or take up on this? At least new npm packages would be nice.

Check Contracts Instead of instanceOf

Currently in the up executable on lines 93 - 97 an instanceOf method is employed to detect that the server will honor the appropriate contract. This breaks however when you have a server that honors the http.Server contract but is not an "instance of" http.Server. In this particular case, a union server.

This means anyone using flatiron, or another union project. Will not be able to deploy using up without some hackery. For the time being I can comment out the exception for the particular error check in the up binary and I can use it just fine.

Would you guys be open to a pull request that checked that the appropriate methods exist instead of using an instanceOf call on http.Server?

How does up work with socket.io?

The most basic example I could come up with, where socket.io is listening to an http server, yielded this warning:

   up test.js --port 8888
   info  - socket.io started
   info  - socket.io started
   warn  - error raised: Error: listen EADDRINUSE
   info  - socket.io started
   warn  - error raised: Error: listen EADDRINUSE

but for my current, larger project, into which I'm hoping to integrate up, I'm using a popular technique of storing a session object inside the handshake authorization and when using up to launch the server encountering these warnings and a lack of socket connectivity:

up ./app/index.js --port 8888
info  - socket.io started
  up-cli starting cluster with 2 workers on port 8888
  up-cli `kill -s SIGUSR2 10331` or ctrl + r to load new code
  up spawning 2 workers from master 10331
  up worker 10333 created
  up worker 10334 created
   info  - socket.io started
  up worker 10333 listening on port 63409
   info  - socket.io started
  up worker 10334 listening on port 63412
   info  - handshake authorized 14777588931060129542
   warn  - client not handshaken client should reconnect
   info  - transport end

I wonder if there's a simple fix available or if this is a part of a larger problem not yet solved...

New 0.2.0 release fail tests

$ git describe --tags
0.2.0
$ make test

  ......

  ✖ 1 of 9 tests failed:

  1) up should suicide workers if master dies:
     Error: expected true to equal false
      at Assertion.assert (.../up/node_modules/expect.js/expect.js:99:13)
      at Assertion.equal (.../up/node_modules/expect.js/expect.js:200:10)
      at Assertion.be (.../up/node_modules/expect.js/expect.js:73:24)
      at Object._onTimeout (.../up/test/up.js:171:33)
      at Timer.ontimeout (timers.js:94:19)


make: *** [test] Error 1

When running on pull request #30 it passes.

$ git describe --tags
0.2.0-3-ga8e8560
$ make test

  .........

  ✔ 9 tests complete (1621ms)

Up and Express?

Will 'up' work with 'express'?
I keep getting an error whenever a request is made:
http.js:562
throw new Error("Can't render headers after they are sent to the client.")

Thanks,
Shawn

Add watch support to javascript

Currently only the cli version of the module supports to watch for file changes, however it would be nice if we could watch files from a program too. Either that or the cli version of up would need to support https as well. The problem with the latter solution would be that we lose the ability to set up a single http server forwarding everything to https while up runs https and socket.io.

Error: "use fs.watch api instead" using the --watch flag on Windows, Node 0.6.6

I'm on Windows 7 32bit. Node 0.6.6. Up 0.1.7.

When I run my app with up server.js it works fine, but when I add the --watch flag (i.e. up server.js --watch) it fails with the error:

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: use fs.watch api instead
    at Object.watchFile (fs.js:734:11)
    at C:\Users\jpoehls\AppData\Roaming\npm\node_modules\up\bin\up:237:10
    at Array.forEach (native)
    at watch (C:\Users\jpoehls\AppData\Roaming\npm\node_modules\up\bin\up:236:11)
    at Object.<anonymous> (C:\Users\jpoehls\AppData\Roaming\npm\node_modules\up\bin\up:249:3)
    at Module._compile (module.js:432:26)
    at Object..js (module.js:450:10)
    at Module.load (module.js:351:31)
    at Function._load (module.js:310:12)
    at Array.0 (module.js:470:10)

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.