npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

spawn-for-ip

v0.3.4

Published

Spawns child processes and allocates `process.env.PORT` for each.

Downloads

3

Readme

spawn-for-ip

Fork of node-spinner, which is a fork of node-spinner, which is a fork of nploy.

I've let the README below pretty much as is, updating only when something changes.

It's been made available on NPM:

npm install spawn-for-ip

Spawns child processes with dynamic port allocation and other goodies. Sort of like forever but with a few more features.

  • Allocates ports dynamically and hands them over child processes via the PORT environment variable
  • Respawn processes that decided to go to bed
  • Stateless API for a pretty stateful module (uses fsmjs).
  • Monitor a file/directory and restart the child if changed
  • If a child was not 'touched' for some time, automatically stop it
$ npm install spinner

myapp.js

var http = require('http');

console.log('[myapp] Started on port %s', process.env.port || 5000);

http.createServer(function(req, res) {
  console.log('[myapp] %s %s', req.method, req.url);
  res.end('hello, world');
}).listen(process.env.port || 5000);

This is a simple node.js HTTP server that binds to process.env.port. It emits some logs which will be piped into the server's stdio streams.

server.js

var http = require('http');
var spinner = require('spinner').createSpinner();

spinner.start('./myapp.js', function(err, socket) {

  var req = http.request({ socketPath: socket });

  req.on('response', function(res) {
    console.log('[server] HTTP %d %s', res.statusCode, http.STATUS_CODES[res.statusCode]);

    res.on('data', function(data) {
      console.log('[server] DATA <' + data.toString() + '>');
    });

    res.on('end', function() {
      spinner.stop('./myapp.js');
    });
  });

  req.end();
});

The server creates a spinner and starts ./myapp.js. The callback receives a socket parameter with the unix domain socket (or named pipe in Windows) path. Then, it uses node's http module to issue an HTTP request into this pipe.

Output:

$ node server.js
[myapp] Started on port /tmp/ed929e3c521e4004bb93c59a65c968b2
[myapp] GET /
[server] HTTP 200 OK
[server] DATA <hello, world>

API

createSpinner(globalOptions)

Returns a spinner. Within a spinner namespace, child processes are identified by name and only a single child can exists for every name.

This means that if I call spinner.start('foo') twice, only a single child will be spawned. The second call will return the same port.

globalOptions may contain any of the options passed along to spinner.start() (except name and args) and used as defaults options for spinner.start.

spinner.start(options, callback)

// Name of child. Basically a key used to identify the child process
name: 'foofoo',

// Program to execute (default is `process.execPath`, which is node.js)
command: process.execPath,

// Array of arguments to use for spawn
args: [ './myapp.js' ],

// Environment variables for spawned process
env: { myenv: '1234' },

// working directory to spawn the app (default null)
cwd: null,

// Logger to use (default is `console`)
logger: console,

// Timeout in seconds waiting for the process to bind to the
// allocated port (default is 30 seconds)
timeout: 30,

// Number of attempts to start the process. After this, spinner will not 
// fail on every `start` request unless a `stop` is issued (default is 3).
attempts: 3,

// Timeout in seconds to wait for a child to stop before issuing a 
// SIGKILL (default is 30 sec)
stopTimeout: 30,

// Path of file or directory to monitor for changes. When the monitor 
// indicates a change, the child will be restarted. Default is null 
// (no monitor). file must exist when the child is first started.
monitor: './lazykiller.js',

// Stream to pipe process stdout to (default is process.stdout). Use `null` to disable.
stdout: process.stdout,

// Stream to pipe process stderr to (default is process.stderr). Use `null` to disable.
stderr: process.stderr,

// Idle time: if `spinner.start` is not called for this process within this time,
// spinner will automatically stop the process. Use `-1` to disable (default is 30 minutes).
idleTimeSec: 30 * 60,

// Number of seconds allowed between unexpected restarts of a child process. If a restart
// happens within less time, the child will be become faulted.
restartTolerance: 60,

// Number of seconds child process is not restarted when it is faulted. If child process
// started again after this timeout expired, another attempt to spawn it will be made.
faultTimeout: 60

The argument callback is function(err, port) where port is the port number allocated for this child process and set in it's PORT environment variable (in node.js: process.env.PORT). If the child could not be started or if it did not bind to the port in the alloted timeout, err will indicate that with an Error object.

spinner.start(script, callback)

A short form for spinner.start() where script is used as the first argument to the node engine prescribed in process.execPath and also used as the name of the child. Monitor is also set to point to the script, so if it changes, the child will be restarted (unless monitor is set to null in the global options).

spinner.stop(name, callback)

Stops the child keyed name. callback is function(err). Spinner sends SIGTERM and after stopTimeout passes, sends SIGKILL.

spinner.stopall(callback)

Stops all the child processes maintained by this spinner.

callback is function(err)

spinner.get(name)

Returns information about a child process named name. The information includes the options used to start the child process and a state property indicating the current state of the child.

Possible states are:

  • stopped - Child is stopped.
  • starting - Child is being spawned and waiting for port to be bound to.
  • started - Child is started.
  • stopping - Child is being stopped.
  • faulted - Child is faulted. That is, the alloted number of start requests failed.
  • restart - Child is being restarted.

spinner.list()

Returns the list of child processes maintained by this spinner. The result is a hash keyed by the child name and contains the details from spinner.get().

Event: 'started'

function(port) {}

Emitted after the child process has been started and bound to port. This means it can be accessed from now on via { host: 'localhost', port: port }.

Event: 'stopped'

function() {}

Emitted after the child process has been stopped.

Event: 'restarted'

function(port) {}

Emitted after the child process has been restarted (either due to a file change or due to a crash).

Event: 'error'

function(e) {}

Emitted when an error occured while starting the child process.

License

MIT

Contributors

Originally forked from forked from nploy by George Stagas (@stagas), but since I had to work out the crazy state machine, not much code of nploy let. Neverthess, it's an awesome lib.