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

forkie

Package Overview
Dependencies
Maintainers
2
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

forkie - npm Package Compare versions

Comparing version 1.2.7 to 1.2.8

.editorconfig

118

lib/master.js

@@ -10,5 +10,6 @@ 'use strict';

var async = require('async');
var workers;
var workers = [];
var repl;
var shutdown;
var shuttingDown = false;

@@ -20,3 +21,2 @@ opts = merge({

restarts: false,
// see https://github.com/dshaw/replify#options

@@ -26,14 +26,16 @@ repl: false

if (opts.restarts === -1) {
opts.restarts = Infinity
}
if (opts.restarts === -1)
opts.restarts = Infinity;
if (opts.repl && opts.repl.path) {
if (opts.repl && opts.repl.path)
opts.repl.path = path.resolve(opts.repl.path);
}
// a master is a worker with a specific behavior
var masterWorker = require('./worker.js')('master process', {
start: async.series.bind(async, [opts.start, start]),
stop: async.series.bind(async, [opts.stop, stop])
start: function (cb) {
async.series([opts.start, start], cb)
},
stop: function (cb) {
async.series([opts.stop, stop], cb)
}
});

@@ -44,3 +46,3 @@

function start(cb) {
debug('starting master %j', toFork);
debug('starting master with forks: %j', toFork);

@@ -54,13 +56,11 @@ workers = toFork.map(function(what) {

toFork: what,
title: 'no title yet',
title: '[' + what + ']',
status: 'unknown',
start: function start(cb) {
debug('starting clusterWorker %s', what);
var clusterWorker = this;
debug('starting clusterWorker "%s"', clusterWorker.title);
if (!cb) {
cb = function() {}
}
if (!cb)
cb = function() {};
var clusterWorker = this;
if (forks[clusterWorker.id] !== null) {

@@ -78,5 +78,6 @@ var err = new Error('Cannot start a started worker');

forks[clusterWorker.id].once('exit', function(code, signal) {
if (shutdown) {
debug('worker "%s" exit detected', clusterWorker.title);
if (shuttingDown)
return;
}

@@ -100,2 +101,3 @@ // if `signal` is defined, it means

debug('attempting to restart worker "%s"...', clusterWorker.title);
clearTimeout(autoRestart);

@@ -110,8 +112,8 @@ autoRestart = setTimeout(function restart() {

});
} else {
forks[clusterWorker.id].once('exit', function workerStopped(code, signal) {
if (shutdown) {
debug('worker "%s" exit detected', clusterWorker.title);
if (shuttingDown)
return;
}

@@ -134,5 +136,3 @@ masterWorker.emit('worker stopped', clusterWorker, {

], function workerStarted(err) {
if (err) {
return cb(err);
}
if (err) return cb(err);

@@ -148,13 +148,12 @@ clusterWorker.status = 'started';

stop: function stop(cb) {
if (!cb) {
cb = function() { }
}
var clusterWorker = this;
debug('stopping clusterWorker "%s"', clusterWorker.title);
var clusterWorker = this;
if (!cb)
cb = function() { };
var err;
if (forks[clusterWorker.id] === null) {
if (shutdown) {
err = null;
} else {
if (!shuttingDown) {
err = new Error('Cannot stop a stopped worker');

@@ -170,5 +169,3 @@ masterWorker.emit('worker error', clusterWorker, err);

kill(clusterWorker, function killed(err, code, signal) {
if (err) {
return cb(err);
}
if (err) return cb(err);

@@ -182,3 +179,3 @@ forks[clusterWorker.id] = null;

} else {
debug('worker stopped at kill', code, signal);
debug('worker "%s" stopped at kill', clusterWorker.title, code, signal);
masterWorker.emit('worker stopped', clusterWorker);

@@ -191,3 +188,7 @@ }

restart: function restart(cb) {
var clusterWorker = this;
debug('REstarting clusterWorker "%s"', clusterWorker.title);
if (manualRestart) {
// Note : should call back ??
return;

@@ -198,3 +199,2 @@ }

var clusterWorker = this;
clusterWorker.stop(function(err) {

@@ -227,17 +227,21 @@ clusterWorker.start(cb);

function stop(cb) {
shutdown = true;
debug('stopping master...');
shuttingDown = true;
async.each(workers, function stopWorker(clusterWorker, cb) {
debug('ordering worker "%s" to stop...', clusterWorker.title);
clusterWorker.stop(cb);
}, function workedStopped(err) {
if(err)
debug('An error happened while stopping all workers : ' + err.message);
else
debug('all workers should have stopped.');
if (repl && repl.close) {
// when repl failed to start, dont fail at closing it
// when repl failed to start, don't fail at closing it
try { repl.close() } catch (er) {}
}
if (err) {
return cb(err);
}
cb(null);
return cb(err);
});

@@ -253,4 +257,6 @@ }

// http://nodejs.org/api/cluster.html
debug('forking "%s" as cluster...', clusterWorker.title);
forked = clusterWorker.toFork.fork();
} else {
debug('forking "%s" as child process...', clusterWorker.title);
forked = fork(clusterWorker.toFork);

@@ -263,2 +269,3 @@ }

function waitForReady(clusterWorker, cb) {
debug('Waiting for worker "%s" readiness...', clusterWorker.title);
var forked = forks[clusterWorker.id];

@@ -277,5 +284,3 @@

forked.on('message', function waitForReady(msg) {
if (!msg.graceful) {
return;
}
if (!msg.graceful) return;

@@ -288,2 +293,3 @@ if (msg.graceful.status === 'ready') {

forked.removeListener('message', waitForReady);
debug('Worker "%s[%s]" signaled its readiness.', clusterWorker.title, clusterWorker.toFork);
masterWorker.emit('worker ready', clusterWorker);

@@ -296,2 +302,4 @@ cb(null);

function kill(clusterWorker, cb) {
debug('Killing worker "%s"...', clusterWorker.title);
var forked = forks[clusterWorker.id];

@@ -322,2 +330,3 @@ var forkedProcess = forked.process || forked;

forkedProcess.once('exit', function waitForExit(code, signal) {
debug('worker "%s" reported its exit.', clusterWorker.title);
clearTimeout(killTimeout);

@@ -329,2 +338,4 @@ cb(null, code, signal);

function startWorker(clusterWorker, cb) {
debug('Starting worker "%s"...', clusterWorker.title);
var forked = forks[clusterWorker.id];

@@ -335,2 +346,3 @@ var startTimeout = setTimeout(cb.bind(null, new Error('Worker could not be started')), 10 * 1000);

function cancel(code, signal) {
debug('worker "%s" reported its exit while we were starting it !', clusterWorker.title);
clearTimeout(startTimeout);

@@ -341,5 +353,4 @@

// - before we get the started message
if (signal !== null) {
if (signal !== null)
return;
}

@@ -353,5 +364,3 @@ // worker failed to start and exited immediately, continue

forked.on('message', function waitForStart(msg) {
if (!msg.graceful) {
return;
}
if (!msg.graceful) return;

@@ -362,2 +371,3 @@ if (msg.graceful.status === 'started') {

forked.removeListener('message', waitForStart);
debug('Worker "%s" signaled it stated.', clusterWorker.title);
cb(null);

@@ -371,2 +381,2 @@ }

return masterWorker;
}
}

@@ -0,1 +1,3 @@

'use strict';
module.exports = repl;

@@ -55,2 +57,2 @@

return server;
}
}

@@ -16,5 +16,5 @@ 'use strict';

var EventEmitter = require('events').EventEmitter;
var emitter = new EventEmitter();
var working;
var isWorking;
var exitAsked;

@@ -25,3 +25,3 @@

fns.start(function() {
debug('starting %d', process.pid);
debug('"%s"/%d starting...', title, process.pid);
if (process.send) {

@@ -35,3 +35,3 @@ process.send({graceful: {status: 'started', title: title}});

stop: function() {
debug('stopping %d', process.pid);
debug('"%s"/%d stopping...', title, process.pid);
teardown();

@@ -69,5 +69,4 @@ fns.stop(function() {

function teardown() {
if (process.send) {
if (process.send)
process.removeListener('message', handleMasterMessage);
}
exitSignals.forEach(unsubscribe);

@@ -77,3 +76,3 @@ }

function subscribe(signal) {
debug('subscribing to signal %s %d', signal, process.pid);
debug('"%s"/%d subscribing to signal %s', title, process.pid, signal);
process.addListener(signal, exitSignalHandler);

@@ -83,3 +82,3 @@ }

function unsubscribe(signal) {
debug('unsubscribing from signal %s %d', signal, process.pid);
debug('"%s"/%d unsubscribing from signal %s', title, process.pid, signal);
try {

@@ -95,5 +94,5 @@ process.removeListener(signal, exitSignalHandler);

if (!quit) {
debug('received %j from master, %d', msg, process.pid);
debug('"%s"/%d received %j from master', title, process.pid, msg);
} else {
debug('was asked by signal to quit, %d', process.pid);
debug('"%s"/%d was asked by signal to quit', title, process.pid);
}

@@ -107,12 +106,15 @@

case 'stop':
if (exitAsked) {
if (exitAsked)
return;
}
exitAsked = true;
if (!working) {
if (!isWorking)
graceful.stop();
}
break;
default:
console.error('Unknown msg.graceful.action ! ' + msg.graceful.action);
debug('"%s"/%d Unknown msg.graceful.action ! ' + msg.graceful.action, title, process.pid);
break;
}

@@ -123,5 +125,5 @@ }

emitter.working = function setWorking(status) {
working = status;
isWorking = status;
if (working === false && exitAsked) {
if (isWorking === false && exitAsked) {
graceful.stop();

@@ -132,3 +134,3 @@ }

function masterDied() {
console.error('Master process died, forced exit of ' + title);
console.error('"%s"/%d Master process died, forced exit', title, process.pid);
process.nextTick(process.exit.bind(process, 1));

@@ -138,2 +140,2 @@ }

return emitter;
}
}
{
"name": "forkie",
"version": "1.2.7",
"version": "1.2.8",
"description": "forkie likes your forks",

@@ -19,16 +19,16 @@ "main": "index.js",

"devDependencies": {
"mocha": "~1.17.0",
"sandboxed-module": "~0.3.0",
"sinon": "~1.8.1",
"chai": "~1.9.0",
"sinon-chai": "~2.5.0",
"lodash.invoke": "~2.4.1",
"log-prefix": "0.0.0"
"chai": "^3.5.0",
"lodash.invokemap": "^4.1.0",
"log-prefix": "0.0.0",
"mocha": "^2.4.5",
"sandboxed-module": "^0.3.0",
"sinon": "^1.17.3",
"sinon-chai": "^2.8.0"
},
"dependencies": {
"async": "~0.9.2",
"debug": "~2.2.0",
"deepmerge": "~0.2.7",
"async": "~0.2.10",
"replify": "git://github.com/vvo/replify#2e4b54333e386d1854b5d465095cb0973ca04167",
"debug": "^0.8.0"
"replify": "git://github.com/vvo/replify#2e4b54333e386d1854b5d465095cb0973ca04167"
}
}

@@ -21,3 +21,3 @@ # Forkie [![Build Status](https://travis-ci.org/vvo/forkie.png?branch=master)](https://travis-ci.org/vvo/forkie) [![Dependency Status](https://david-dm.org/vvo/forkie.png?theme=shields.io)](https://david-dm.org/vvo/forkie) [![devDependency Status](https://david-dm.org/vvo/forkie/dev-status.png?theme=shields.io)](https://david-dm.org/vvo/forkie#info=devDependencies)

A forkie master will forks all the workers you give to him.
Workers must implement the [worker API](#worker API).
Workers must implement the [worker API](#worker-api).

@@ -24,0 +24,0 @@ ```js

// chai
var chai = require('chai');
chai.Assertion.includeStack = true;
chai.config.includeStack = true;
chai.use(require('sinon-chai'));

@@ -5,0 +5,0 @@

@@ -0,9 +1,12 @@

'use strict';
var EventEmitter = require('events').EventEmitter;
var SandboxedModule = require('sandboxed-module');
var invokemap = require('lodash.invokemap');
describe('creating a graceful master process', function () {
var EventEmitter = require('events').EventEmitter;
var SandboxedModule = require('sandboxed-module');
var invoke= require('lodash.invoke');
var processMock;
var workerMock;
var childProcessMock;
var fakeProcess;
var fakeWorker;
var fakeCp;
var gracefulMaster;

@@ -16,2 +19,3 @@ var master;

var stopCb;
var workerEmit;

@@ -26,4 +30,4 @@ beforeEach(function () {

forks = [];
fakeProcess = new EventEmitter();
fakeProcess.nextTick = sinon.spy(function(cb) {
processMock = new EventEmitter();
processMock.nextTick = sinon.spy(function(cb) {
cb();

@@ -33,5 +37,5 @@ });

// graceful worker minimal mock for master
fakeWorker = sinon.spy(function(title, fns) {
workerMock = sinon.spy(function(title, fns) {
process.nextTick(fns.start.bind(null, startCb));
fakeProcess.on('SIGTERM', fns.stop.bind(null, stopCb));
processMock.on('SIGTERM', fns.stop.bind(null, stopCb));
return {

@@ -42,3 +46,3 @@ emit: workerEmit

fakeCp = {
childProcessMock = {
fork: sinon.spy(function(what) {

@@ -57,7 +61,7 @@ var fork = new EventEmitter();

requires: {
'./worker.js': fakeWorker,
'child_process': fakeCp
'./worker.js': workerMock,
'child_process': childProcessMock
},
globals: {
process: fakeProcess
process: processMock
}

@@ -72,3 +76,3 @@ }

describe('with filenames to fork', function () {
context('with filenames to fork', function () {

@@ -84,9 +88,9 @@ beforeEach(function(done) {

it('forked the first module', function() {
expect(fakeCp.fork).to.be.calledOnce;
expect(fakeCp.fork).to.be.calledWithExactly('a-module.js');
it('forks the first module', function() {
expect(childProcessMock.fork).to.have.been.calledOnce;
expect(childProcessMock.fork).to.have.been.calledWithExactly('a-module.js');
expect(forks).to.length(1);
});
describe('when fork is ready', function () {
context('when fork is ready', function () {

@@ -103,4 +107,4 @@ beforeEach(function () {

it('emits ready event', function() {
expect(workerEmit).to.be.calledOnce;
expect(workerEmit).to.be.calledWithMatch('worker ready', {
expect(workerEmit).to.have.been.calledOnce;
expect(workerEmit).to.have.been.calledWithMatch('worker ready', {
id: 0,

@@ -114,7 +118,7 @@ title: 'omg',

});
})
});
it('asks for process start', function() {
expect(send).to.be.calledOnce;
expect(send).to.be.calledWithExactly({
expect(send).to.have.been.calledOnce;
expect(send).to.have.been.calledWithExactly({
graceful: {

@@ -126,3 +130,3 @@ action: 'start'

describe('when fork starts', function () {
context('when fork starts', function () {
beforeEach(function () {

@@ -138,4 +142,4 @@ workerEmit.reset();

it('emits a started event', function() {
expect(workerEmit).to.be.calledOnce;
expect(workerEmit).to.be.calledWithMatch('worker started', {
expect(workerEmit).to.have.been.calledOnce;
expect(workerEmit).to.have.been.calledWithMatch('worker started', {
id: 0,

@@ -151,3 +155,3 @@ toFork: 'a-module.js',

describe('when second process is started', function() {
context('when second process is started', function() {
beforeEach(function() {

@@ -171,4 +175,4 @@ workerEmit.reset();

it('starts second worker', function() {
expect(workerEmit).to.be.calledTwice;
expect(workerEmit).to.be.calledWithMatch('worker ready', {
expect(workerEmit).to.have.been.calledTwice;
expect(workerEmit).to.have.been.calledWithMatch('worker ready', {
id: 1,

@@ -182,3 +186,3 @@ toFork: 'another-module.js',

});
expect(workerEmit).to.be.calledWithMatch('worker started', {
expect(workerEmit).to.have.been.calledWithMatch('worker started', {
id: 1,

@@ -195,6 +199,6 @@ toFork: 'another-module.js',

it('calls startCb', function() {
expect(startCb).to.be.calledOnce;
expect(startCb).to.have.been.calledOnce;
});
describe('when forks are connected', function () {
context('when forks are connected', function () {
beforeEach(function () {

@@ -209,8 +213,8 @@ forks.forEach(function(fork) {

send.reset();
fakeProcess.emit('SIGTERM');
processMock.emit('SIGTERM');
});
it('gently ask the forks to stop', function() {
expect(send).to.be.calledTwice;
expect(send).to.be.calledWithExactly({
expect(send).to.have.been.calledTwice;
expect(send).to.have.been.calledWithExactly({
graceful: {

@@ -222,14 +226,14 @@ action: 'stop'

describe('when worker stops', function () {
context('when worker stops', function () {
beforeEach(function () {
workerEmit.reset();
invoke(forks, 'emit', 'exit', 0);
invokemap(forks, 'emit', 'exit', 0);
});
it('emits a worker stopped event', function() {
expect(workerEmit).to.be.calledTwice;
expect(workerEmit).to.be.calledWithMatch('worker stopped', {
expect(workerEmit).to.have.been.calledTwice;
expect(workerEmit).to.have.been.calledWithMatch('worker stopped', {
title: 'omg'
});
expect(workerEmit).to.be.calledWithMatch('worker stopped', {
expect(workerEmit).to.have.been.calledWithMatch('worker stopped', {
title: 'oh great'

@@ -240,7 +244,7 @@ });

it('calls stopCb', function() {
expect(stopCb).to.be.calledOnce;
expect(stopCb).to.have.been.calledOnce;
});
});
describe('when worker does not stops fast enough', function () {
context('when worker does not stop fast enough', function () {
beforeEach(function () {

@@ -251,4 +255,4 @@ this.clock.tick(5 * 1000);

it('kills the worker with SIGKILL', function() {
expect(kill).to.be.calledTwice;
expect(kill).to.be.calledWithExactly('SIGKILL');
expect(kill).to.have.been.calledTwice;
expect(kill).to.have.been.calledWithExactly('SIGKILL');
});

@@ -259,11 +263,11 @@

workerEmit.reset();
invoke(forks, 'emit', 'exit', 1, 'SIGKILL');
invokemap(forks, 'emit', 'exit', 1, 'SIGKILL');
});
it('emits a worker killed event', function() {
expect(workerEmit).to.be.calledTwice;
expect(workerEmit).to.be.calledWithMatch('worker killed', {
expect(workerEmit).to.have.been.calledTwice;
expect(workerEmit).to.have.been.calledWithMatch('worker killed', {
title: 'omg'
});
expect(workerEmit).to.be.calledWithMatch('worker killed', {
expect(workerEmit).to.have.been.calledWithMatch('worker killed', {
title: 'oh great'

@@ -277,10 +281,10 @@ });

describe('when forks are not connected', function () {
describe('and we receive a SIGTERM', function () {
context('when forks are not connected', function () {
context('and we receive a SIGTERM', function () {
beforeEach(function () {
fakeProcess.emit('SIGTERM');
processMock.emit('SIGTERM');
});
it('calls fork.kill', function() {
expect(kill).to.be.calledTwice;
expect(kill).to.have.been.calledTwice;
});

@@ -290,3 +294,3 @@ });

describe('when fork failed', function () {
context('when fork failed', function () {
beforeEach(function() {

@@ -296,5 +300,5 @@ forks[0].exitCode = 8;

describe('and we receive a SIGTERM', function () {
context('and we receive a SIGTERM', function () {
beforeEach(function () {
fakeProcess.emit('SIGTERM');
processMock.emit('SIGTERM');
forks[1].emit('exit', 0);

@@ -304,3 +308,3 @@ });

it('reaches stopCb', function() {
expect(stopCb).to.be.calledOnce;
expect(stopCb).to.have.been.calledOnce;
});

@@ -310,3 +314,3 @@ });

describe('when cluster fork failed', function () {
context('when cluster fork failed', function () {
beforeEach(function() {

@@ -316,5 +320,5 @@ forks[0].process = { exitCode: 8 };

describe('and we receive a SIGTERM', function () {
context('and we receive a SIGTERM', function () {
beforeEach(function () {
fakeProcess.emit('SIGTERM');
processMock.emit('SIGTERM');
forks[1].emit('exit', 0);

@@ -324,7 +328,6 @@ });

it('reaches stopCb', function() {
expect(stopCb).to.be.calledOnce;
expect(stopCb).to.have.been.calledOnce;
});
});
});
});

@@ -335,3 +338,3 @@ });

describe('with cluster workers to fork', function () {
context('with cluster workers to fork', function () {
var fork = sinon.stub().returns(new EventEmitter);

@@ -350,7 +353,7 @@

it('called fork once', function() {
expect(fork).to.be.calledOnce;
expect(fork).to.have.been.calledOnce;
})
});
describe('when using a specific start function', function () {
context('when using a specific start function', function () {
var start = sinon.stub().yields();

@@ -369,9 +372,9 @@

it('calls functions in the right order', function() {
expect(fakeCp.fork).to.be.calledOnce;
expect(start).to.be.calledOnce;
expect(start).to.be.calledBefore(fakeCp.fork);
expect(childProcessMock.fork).to.have.been.calledOnce;
expect(start).to.have.been.calledOnce;
expect(start).to.have.been.calledBefore(childProcessMock.fork);
});
});
describe('when using a specific stop function', function () {
context('when using a specific stop function', function () {
var stop = sinon.stub().yields();

@@ -391,24 +394,24 @@

describe('when worker is not connected', function () {
context('when worker is not connected', function () {
beforeEach(function () {
fakeProcess.emit('SIGTERM');
processMock.emit('SIGTERM');
});
it('calls function in the right order', function() {
expect(stop).to.be.calledOnce;
expect(kill).to.be.calledOnce;
expect(stop).to.be.calledBefore(kill);
expect(stop).to.have.been.calledOnce;
expect(kill).to.have.been.calledOnce;
expect(stop).to.have.been.calledBefore(kill);
});
});
describe('when worker is connected', function () {
context('when worker is connected', function () {
beforeEach(function () {
forks[0].connected = true;
fakeProcess.emit('SIGTERM');
processMock.emit('SIGTERM');
});
it('calls function in the right order', function() {
expect(stop).to.be.calledOnce;
expect(send).to.be.calledOnce;
expect(stop).to.be.calledBefore(send);
expect(stop).to.have.been.calledOnce;
expect(send).to.have.been.calledOnce;
expect(stop).to.have.been.calledBefore(send);
});

@@ -456,12 +459,11 @@ });

// two times: init and restart
expect(fakeCp.fork).to.be.calledTwice;
expect(fakeCp.fork).to.be.calledWithExactly('a-restarted-module.js');
expect(childProcessMock.fork).to.have.been.calledTwice;
expect(childProcessMock.fork).to.have.been.calledWithExactly('a-restarted-module.js');
});
it('sends a restarted event', function() {
expect(workerEmit).to.be.calledWithMatch('worker restarted', {
expect(workerEmit).to.have.been.calledWithMatch('worker restarted', {
restarts: { manual: 0, automatic: 1 }
});
});
});

@@ -477,3 +479,3 @@

it('do not call fork again', function() {
expect(fakeCp.fork).to.be.calledOnce;
expect(childProcessMock.fork).to.have.been.calledOnce;
});

@@ -488,3 +490,2 @@

});
});

@@ -498,3 +499,3 @@

it('does not call fork again', function() {
expect(fakeCp.fork).to.be.calledOnce;
expect(childProcessMock.fork).to.have.been.calledOnce;
});

@@ -509,5 +510,3 @@

});
});
});

@@ -525,16 +524,14 @@

// two times: init and restart
expect(fakeCp.fork).to.be.calledTwice;
expect(fakeCp.fork).to.be.calledWithExactly('a-restarted-module.js');
expect(childProcessMock.fork).to.have.been.calledTwice;
expect(childProcessMock.fork).to.have.been.calledWithExactly('a-restarted-module.js');
});
it('sends a restarted event', function() {
expect(workerEmit).to.be.calledWithMatch('worker restarted', {
expect(workerEmit).to.have.been.calledWithMatch('worker restarted', {
restarts: { manual: 0, automatic: 1 }
});
});
});
});
});
});
});

@@ -0,6 +1,8 @@

'use strict';
var EventEmitter = require('events').EventEmitter;
var SandboxedModule = require('sandboxed-module');
describe('creating a graceful process', function() {
var EventEmitter = require('events').EventEmitter;
var SandboxedModule = require('sandboxed-module');
var fakeProcess;
var processMock;
var graceful;

@@ -11,6 +13,8 @@ var worker;

this.clock = sinon.useFakeTimers();
fakeProcess = new EventEmitter();
fakeProcess.version = 'gotohell-2.0';
fakeProcess.nextTick = sinon.stub().yieldsAsync();
processMock = new EventEmitter();
processMock.version = 'gotohell-2.0';
processMock.nextTick = sinon.stub().yieldsAsync();
processMock.pid = 99999; // for logs
worker = {

@@ -26,7 +30,7 @@ start: sinon.stub().yields(),

describe('when not started as a fork', function() {
context('when not started as a fork', function() {
beforeEach(function (done) {
var gracefulWorker = SandboxedModule.require(
'../../lib/worker.js', {
globals: {process: fakeProcess}
globals: {process: processMock}
}

@@ -44,14 +48,14 @@ );

it('calls worker.start', function() {
expect(worker.start).to.be.called.once;
expect(worker.start).to.have.been.called.once;
});
it('emits a started event', function() {
expect(graceful.emit).to.be.calledWith('started');
expect(graceful.emit).to.have.been.calledWith('started');
});
describe('receiving a SIGTERM while busy', function () {
context('on receiving a SIGTERM while busy', function () {
beforeEach(function (done) {
graceful.working(true);
fakeProcess.once('SIGTERM', done);
fakeProcess.emit('SIGTERM');
processMock.once('SIGTERM', done);
processMock.emit('SIGTERM');
});

@@ -67,3 +71,3 @@

describe('when we are not busy anymore', function() {
context('when we are not busy anymore', function() {
beforeEach(function () {

@@ -74,3 +78,3 @@ graceful.working(false);

it('calls worker.stop', function() {
expect(worker.stop).to.be.called.once;
expect(worker.stop).to.have.been.called.once;
expect(worker.stop.getCall(0).args[0]).to.be.a.Function;

@@ -80,3 +84,3 @@ });

it('emits a stopped event', function() {
expect(graceful.emit).to.be.calledWith('stopped');
expect(graceful.emit).to.have.been.calledWith('stopped');
});

@@ -86,10 +90,10 @@ });

describe('receiving a SIGTERM while not busy', function () {
context('on receiving a SIGTERM while not busy', function () {
beforeEach(function (done) {
fakeProcess.once('SIGTERM', done);
fakeProcess.emit('SIGTERM');
processMock.once('SIGTERM', done);
processMock.emit('SIGTERM');
});
it('calls worker.stop', function() {
expect(worker.stop).to.be.called.once;
expect(worker.stop).to.have.been.called.once;
expect(worker.stop.getCall(0).args[0]).to.be.a.Function;

@@ -100,9 +104,9 @@ });

describe('when started as a fork', function () {
context('when started as a fork', function () {
beforeEach(function (done) {
fakeProcess.send = sinon.spy();
fakeProcess.disconnect = sinon.spy();
processMock.send = sinon.spy();
processMock.disconnect = sinon.spy();
var gracefulWorker = SandboxedModule.require(
'../../lib/worker.js', {
globals: {process: fakeProcess}
globals: {process: processMock}
}

@@ -116,7 +120,7 @@ );

it('emits a ready event', function() {
expect(graceful.emit).to.be.calledWith('ready');
expect(graceful.emit).to.have.been.calledWith('ready');
});
it('sends a ready message to master', function() {
expect(fakeProcess.send).to.be.calledWith({
expect(processMock.send).to.have.been.calledWith({
graceful: {

@@ -133,18 +137,18 @@ status: 'ready',

describe('when receiving a SIGTERM', function () {
context('when receiving a SIGTERM', function () {
beforeEach(function (done) {
fakeProcess.once('SIGTERM', done);
fakeProcess.emit('SIGTERM');
processMock.once('SIGTERM', done);
processMock.emit('SIGTERM');
});
it('calls worker.stop', function() {
expect(worker.stop).to.be.called.once;
expect(worker.stop).to.have.been.called.once;
});
it('emits a stoped event', function() {
expect(graceful.emit).to.be.calledWith('stopped');
expect(graceful.emit).to.have.been.calledWith('stopped');
});
it('informs master through the communication channel', function() {
expect(fakeProcess.send).to.be.calledWith({
expect(processMock.send).to.have.been.calledWith({
graceful: {

@@ -158,10 +162,10 @@ status: 'stopped',

describe('when master disconnects while stopping', function() {
context('when master disconnects while stopping', function() {
beforeEach(function (done) {
sinon.stub(console, 'error');
worker.stop = sinon.stub().yieldsAsync();
fakeProcess.exit = sinon.spy();
fakeProcess.emit('SIGTERM');
processMock.exit = sinon.spy();
processMock.emit('SIGTERM');
process.nextTick(function() {
fakeProcess.emit('disconnect')
processMock.emit('disconnect')
});

@@ -173,5 +177,5 @@ process.nextTick(done);

process.nextTick(function() {
expect(fakeProcess.exit).to.be.called.once;
expect(fakeProcess.exit).to.be.calledWith(1);
expect(console.error).to.be.calledWith('Master process died, forced exit of a forked worker');
expect(processMock.exit).to.have.been.called.once;
expect(processMock.exit).to.have.been.calledWith(1);
expect(console.error).to.have.been.calledWith('"%s"/%d Master process died, forced exit', 'a forked worker', 99999);
done();

@@ -187,7 +191,7 @@ });

describe('when master disconnects', function () {
context('when master disconnects', function () {
beforeEach(function () {
fakeProcess.exit = sinon.spy();
processMock.exit = sinon.spy();
sinon.stub(console, 'error');
fakeProcess.emit('disconnect');
processMock.emit('disconnect');
});

@@ -197,5 +201,5 @@

process.nextTick(function() {
expect(fakeProcess.exit).to.be.called.once;
expect(fakeProcess.exit).to.be.calledWith(1);
expect(console.error).to.be.calledWith('Master process died, forced exit of a forked worker');
expect(processMock.exit).to.have.been.called.once;
expect(processMock.exit).to.have.been.calledWith(1);
expect(console.error).to.have.been.calledWith('"%s"/%d Master process died, forced exit', 'a forked worker', 99999);
done();

@@ -210,19 +214,19 @@ });

describe('when master asks for start', function () {
context('when master asks for start', function () {
beforeEach(function () {
fakeProcess.emit('message', {graceful: {action: 'start'}});
processMock.emit('message', {graceful: {action: 'start'}});
});
it('calls worker.start', function() {
expect(worker.start).to.be.called.once;
expect(worker.start).to.have.been.called.once;
});
it('emits a started event', function() {
expect(graceful.emit).to.be.called.once;
expect(graceful.emit).to.be.calledWith('started');
expect(graceful.emit).to.have.been.called.once;
expect(graceful.emit).to.have.been.calledWith('started');
});
it('sends a started message to the master', function() {
expect(fakeProcess.send).to.be.called.once;
expect(fakeProcess.send).to.be.calledWith({
expect(processMock.send).to.have.been.called.once;
expect(processMock.send).to.have.been.calledWith({
graceful: {

@@ -236,6 +240,6 @@ status: 'started',

it('make calls in the right order', function() {
expect(worker.start).to.be.calledBefore(fakeProcess.send);
expect(worker.start).to.have.been.calledBefore(processMock.send);
});
});
});
});
});

Sorry, the diff of this file is not supported yet

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