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

@godaddy/terminus

Package Overview
Dependencies
Maintainers
6
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@godaddy/terminus - npm Package Compare versions

Comparing version 2.2.0 to 2.2.1

example/cassandra/Dockerfile

24

example/index.js

@@ -1,19 +0,17 @@

const express = require('express');
const http = require('http');
const terminus = require('../lib/terminus');
const app = express();
const express = require('express')
const http = require('http')
const terminus = require('../lib/terminus')
const app = express()
app.get('/', (req, res) => {
setTimeout(() => {
res.send('ok');
}, 100000);
});
res.send('ok')
}, 100000)
})
function onHealthCheck() {
return Promise.resolve();
}
terminus(http.createServer(app), {
logger: console.log,
onHealthCheck
}).listen(3000);
healthChecks: {
'/healthz': () => Promise.resolve()
}
}).listen(3000)

@@ -1,2 +0,2 @@

'use strict';
module.exports = require('./lib/terminus');
'use strict'
module.exports = require('./lib/terminus')

@@ -1,7 +0,7 @@

'use strict';
const http = require('http');
const server = http.createServer((req, res) => res.end('hello'));
'use strict'
const http = require('http')
const server = http.createServer((req, res) => res.end('hello'))
const terminus = require('../terminus');
const SIGNAL = 'SIGINT';
const terminus = require('../terminus')
const SIGNAL = 'SIGINT'

@@ -11,12 +11,12 @@ terminus(server, {

onSignal: () => {
console.log('on-sigint-runs');
return Promise.resolve();
console.log('on-sigint-runs')
return Promise.resolve()
},
onShutdown: () => {
console.log('on-shutdown-runs');
console.log('on-shutdown-runs')
}
});
})
server.listen(8000, () => {
process.kill(process.pid, SIGNAL);
});
process.kill(process.pid, SIGNAL)
})

@@ -1,19 +0,19 @@

'use strict';
const http = require('http');
const server = http.createServer((req, res) => res.end('hello'));
'use strict'
const http = require('http')
const server = http.createServer((req, res) => res.end('hello'))
const terminus = require('../terminus');
const terminus = require('../terminus')
terminus(server, {
onSignal: () => {
console.log('on-sigterm-runs');
return Promise.resolve();
console.log('on-sigterm-runs')
return Promise.resolve()
},
onShutdown: () => {
console.log('on-shutdown-runs');
console.log('on-shutdown-runs')
}
});
})
server.listen(8000, () => {
process.kill(process.pid, 'SIGTERM');
});
process.kill(process.pid, 'SIGTERM')
})

@@ -1,7 +0,7 @@

'use strict';
const http = require('http');
const server = http.createServer((req, res) => res.end('hello'));
'use strict'
const http = require('http')
const server = http.createServer((req, res) => res.end('hello'))
const terminus = require('../terminus');
const SIGNAL = 'SIGINT';
const terminus = require('../terminus')
const SIGNAL = 'SIGINT'

@@ -11,9 +11,9 @@ terminus(server, {

onSignal: () => {
console.log('on-sigint-runs');
return Promise.resolve();
console.log('on-sigint-runs')
return Promise.resolve()
}
});
})
server.listen(8000, () => {
process.kill(process.pid, SIGNAL);
});
process.kill(process.pid, SIGNAL)
})

@@ -1,16 +0,16 @@

'use strict';
const http = require('http');
const server = http.createServer((req, res) => res.end('hello'));
'use strict'
const http = require('http')
const server = http.createServer((req, res) => res.end('hello'))
const terminus = require('../terminus');
const terminus = require('../terminus')
terminus(server, {
onSignal: () => {
console.log('on-sigterm-runs');
return Promise.resolve();
console.log('on-sigterm-runs')
return Promise.resolve()
}
});
})
server.listen(8000, () => {
process.kill(process.pid, 'SIGTERM');
});
process.kill(process.pid, 'SIGTERM')
})

@@ -1,92 +0,113 @@

'use strict';
const stoppable = require('stoppable');
const promisify = require('es6-promisify');
'use strict'
const stoppable = require('stoppable')
const { promisify } = require('es6-promisify')
const SUCCESS_RESPONSE = JSON.stringify({
status: 'ok'
});
})
const FAILURE_RESPONSE = JSON.stringify({
status: 'error'
});
})
function noopResolves() {
return Promise.resolve();
function noopResolves () {
return Promise.resolve()
}
function noop() {}
function sendSuccess (res) {
res.statusCode = 200
res.end(SUCCESS_RESPONSE)
}
function decorateWithHealthCheck(server, options) {
const { healthChecks, logger } = options;
function sendFailure (res) {
res.statusCode = 503
res.end(FAILURE_RESPONSE)
}
const state = {
isShuttingDown: false
}
function noop () {}
function decorateWithHealthCheck (server, options) {
const { healthChecks, logger } = options
server.listeners('request').forEach((listener) => {
server.removeListener('request', listener);
server.removeListener('request', listener)
server.on('request', (req, res) => {
if (healthChecks[req.url]) {
if (state.isShuttingDown) {
return sendFailure(res)
}
healthChecks[req.url]()
.then(() => {
res.statusCode = 200;
res.end(SUCCESS_RESPONSE);
sendSuccess(res)
})
.catch((error) => {
logger('healthcheck failed', error);
res.statusCode = 503;
res.end(FAILURE_RESPONSE);
});
logger('healthcheck failed', error)
sendFailure(res)
})
} else {
listener(req, res);
listener(req, res)
}
});
});
})
})
}
function decorateWithSignalHandler(server, options) {
const { signal, onSignal, onShutdown, timeout, logger } = options;
function decorateWithSignalHandler (server, options) {
const { signal, onSignal, beforeShutdown, onShutdown, timeout, logger } = options
stoppable(server, timeout);
stoppable(server, timeout)
const asyncServerStop = promisify(server.stop).bind(server);
const asyncServerStop = promisify(server.stop).bind(server)
function cleanup() {
asyncServerStop()
function cleanup () {
state.isShuttingDown = true
beforeShutdown()
.then(() => asyncServerStop())
.then(() => onSignal())
.then(() => onShutdown())
.then(() => {
process.removeListener(signal, cleanup);
process.kill(process.pid, signal);
process.removeListener(signal, cleanup)
process.kill(process.pid, signal)
})
.catch((error) => {
logger('error happened during shutdown', error);
process.exit(1);
});
logger('error happened during shutdown', error)
process.exit(1)
})
}
process.on(signal, cleanup);
process.on(signal, cleanup)
}
function terminus(server, options = {}) {
const healthChecks = options.healthChecks || {};
function terminus (server, options = {}) {
const { signal='SIGTERM',
timeout=1000,
healthChecks={},
onShutdown=noopResolves,
beforeShutdown=noopResolves,
logger=noop } = options
const onSignal = options.onSignal || options.onSigterm || noopResolves
const signal = options.signal || 'SIGTERM';
const timeout = options.timeout || 1000;
const onSignal = options.onSignal || options.onSigterm || noopResolves;
const onShutdown = options.onShutdown || noopResolves;
if (Object.keys(healthChecks).length > 0) {
decorateWithHealthCheck(server, {
healthChecks,
logger
})
}
const logger = options.logger || noop;
decorateWithHealthCheck(server, {
healthChecks,
logger
});
decorateWithSignalHandler(server, {
signal,
onSignal,
beforeShutdown,
onShutdown,
timeout,
logger
});
})
return server;
return server
}
module.exports = terminus;
module.exports = terminus

@@ -1,25 +0,25 @@

'use strict';
const http = require('http');
const { execFileSync } = require('child_process');
'use strict'
const http = require('http')
const { execFile, execFileSync } = require('child_process')
const expect = require('chai').expect;
const fetch = require('node-fetch');
const expect = require('chai').expect
const fetch = require('node-fetch')
const terminus = require('./terminus');
const terminus = require('./terminus')
describe('Terminus', () => {
let server;
let server
beforeEach(() => {
server = http.createServer((req, res) => res.end('hello'));
});
server = http.createServer((req, res) => res.end('hello'))
})
afterEach(() => {
server.close();
});
server.close()
})
describe('supports onHealthcheck for the healthcheck route', () => {
it('but keeps all the other endpoints', (done) => {
terminus(server, {});
server.listen(8000);
terminus(server, {})
server.listen(8000)

@@ -29,10 +29,10 @@ fetch('http://localhost:8000')

.then(responseText => {
expect(responseText).to.eql('hello');
done();
expect(responseText).to.eql('hello')
done()
})
.catch(done);
});
.catch(done)
})
it('returns 200 on resolve', (done) => {
let onHealthCheckRan = false;
let onHealthCheckRan = false

@@ -42,21 +42,21 @@ terminus(server, {

'/health': () => {
onHealthCheckRan = true;
return Promise.resolve();
onHealthCheckRan = true
return Promise.resolve()
}
}
});
server.listen(8000);
})
server.listen(8000)
fetch('http://localhost:8000/health')
.then(res => {
expect(res.status).to.eql(200);
expect(onHealthCheckRan).to.eql(true);
done();
expect(res.status).to.eql(200)
expect(onHealthCheckRan).to.eql(true)
done()
})
.catch(done);
});
.catch(done)
})
it('returns 503 on reject', (done) => {
let onHealthCheckRan = false;
let loggerRan = false;
let onHealthCheckRan = false
let loggerRan = false

@@ -66,66 +66,80 @@ terminus(server, {

'/health': () => {
onHealthCheckRan = true;
return Promise.reject(new Error('failed'));
onHealthCheckRan = true
return Promise.reject(new Error('failed'))
}
},
logger: () => {
loggerRan = true;
loggerRan = true
}
});
server.listen(8000);
})
server.listen(8000)
fetch('http://localhost:8000/health')
.then(res => {
expect(res.status).to.eql(503);
expect(onHealthCheckRan).to.eql(true);
expect(loggerRan).to.eql(true);
done();
expect(res.status).to.eql(503)
expect(onHealthCheckRan).to.eql(true)
expect(loggerRan).to.eql(true)
done()
})
.catch(done);
});
});
.catch(done)
})
it('returns 503 once signal received', (done) => {
execFile('node', ['lib/standalone-tests/terminus.onsignal.fail.js'])
// let the process start up
setTimeout(() => {
fetch('http://localhost:8000/health')
.then(res => {
expect(res.status).to.eql(503)
done()
})
.catch(done)
}, 300)
})
})
it('runs onSigterm when getting the SIGTERM signal', () => {
try {
execFileSync('node', ['lib/standalone-tests/terminus.onsigterm.js']);
execFileSync('node', ['lib/standalone-tests/terminus.onsigterm.js'])
} catch (ex) {
expect(ex.stdout.toString().trim()).to.eql('on-sigterm-runs');
return;
expect(ex.stdout.toString().trim()).to.eql('on-sigterm-runs')
return
}
throw new Error('running the test should throw, as the exitcode is not 0');
});
throw new Error('running the test should throw, as the exitcode is not 0')
})
it('runs onShutdown after onSigterm', () => {
try {
execFileSync('node', ['lib/standalone-tests/terminus.onshutdown.sigterm.js']);
execFileSync('node', ['lib/standalone-tests/terminus.onshutdown.sigterm.js'])
} catch (ex) {
expect(ex.stdout.toString().trim()).to.eql('on-sigterm-runs\non-shutdown-runs');
return;
expect(ex.stdout.toString().trim()).to.eql('on-sigterm-runs\non-shutdown-runs')
return
}
throw new Error('running the test should throw, as the exitcode is not 0');
});
throw new Error('running the test should throw, as the exitcode is not 0')
})
it('runs onSigint when getting SIGINT signal', () => {
try {
execFileSync('node', ['lib/standalone-tests/terminus.onsigint.js']);
execFileSync('node', ['lib/standalone-tests/terminus.onsigint.js'])
} catch (ex) {
expect(ex.stdout.toString().trim()).to.eql('on-sigint-runs');
return;
expect(ex.stdout.toString().trim()).to.eql('on-sigint-runs')
return
}
throw new Error('running the test should throw, as the exitcode is not 0');
});
throw new Error('running the test should throw, as the exitcode is not 0')
})
it('runs onShutdown after onSigint', () => {
try {
execFileSync('node', ['lib/standalone-tests/terminus.onshutdown.sigint.js']);
execFileSync('node', ['lib/standalone-tests/terminus.onshutdown.sigint.js'])
} catch (ex) {
expect(ex.stdout.toString().trim()).to.eql('on-sigint-runs\non-shutdown-runs');
return;
expect(ex.stdout.toString().trim()).to.eql('on-sigint-runs\non-shutdown-runs')
return
}
throw new Error('running the test should throw, as the exitcode is not 0');
});
});
throw new Error('running the test should throw, as the exitcode is not 0')
})
})

@@ -1,1 +0,42 @@

{"name":"@godaddy/terminus","version":"2.2.0","description":"","main":"index.js","types":"./typings/index.d.ts","scripts":{"test-typings":"tsc --lib ES2015 --noEmit typings/*.ts","test":"mocha lib/**/*.spec.js && npm run test-typings","eslint":"eslint-godaddy -c .eslintrc lib example index.js","coverage":"nyc mocha lib/**/*.spec.js","publish":"npm run eslint && npm test","semantic-release":"semantic-release pre && npm publish && semantic-release post"},"repository":{"type":"git","url":"https://github.com/godaddy/terminus.git"},"keywords":[],"author":"","license":"MIT","dependencies":{"es6-promisify":"^5.0.0","stoppable":"^1.0.5"},"devDependencies":{"@types/express":"^4.0.39","@types/koa":"^2.0.42","@types/node":"^8.0.58","chai":"^4.1.2","eslint":"^4.4.1","eslint-config-godaddy":"^2.0.0","eslint-plugin-json":"^1.2.0","eslint-plugin-mocha":"^4.11.0","express":"^4.16.2","mocha":"^4.0.1","node-fetch":"^1.7.3","nyc":"^11.3.0","semantic-release":"^8.2.0","supertest":"^3.0.0","typescript":"^2.6.2"}}
{
"name": "@godaddy/terminus",
"version": "2.2.1",
"description": "",
"main": "index.js",
"types": "./typings/index.d.ts",
"scripts": {
"test-typings": "tsc --lib ES2015 --noEmit typings/*.ts",
"test": "mocha lib/**/*.spec.js && npm run test-typings",
"lint": "standard --fix --env mocha",
"coverage": "nyc mocha lib/**/*.spec.js",
"publish": "npm run lint && npm test",
"semantic-release": "semantic-release",
"travis-deploy-once": "travis-deploy-once"
},
"repository": {
"type": "git",
"url": "https://github.com/godaddy/terminus.git"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"es6-promisify": "^6.0.0",
"stoppable": "^1.0.5"
},
"devDependencies": {
"@types/express": "^4.0.39",
"@types/koa": "^2.0.42",
"@types/node": "^10.0.7",
"chai": "^4.1.2",
"express": "^4.16.2",
"mocha": "^5.0.0",
"node-fetch": "^2.0.0",
"nyc": "^11.3.0",
"semantic-release": "^15.5.1",
"standard": "^11.0.1",
"supertest": "^3.0.0",
"typescript": "^2.6.2",
"travis-deploy-once": "^5.0.0"
}
}
[![Build Status](https://travis-ci.org/godaddy/terminus.svg?branch=master)](https://travis-ci.org/godaddy/terminus)
[![Greenkeeper badge](https://badges.greenkeeper.io/godaddy/terminus.svg)](https://greenkeeper.io/)
# terminus

@@ -7,2 +9,10 @@

## Installation
Install via npm:
```console
$ npm i @godaddy/terminus --save
```
## Usage

@@ -14,3 +24,3 @@

function onSigterm () {
function onSignal () {
console.log('server is starting cleanup');

@@ -27,6 +37,12 @@ return Promise.all([

const server = http.createServer((request, response) => {
response.end('<html><body><h1>Hello, World!</h1></body></html>');
response.end(
`<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>`
);
})
terminus(server, {
const options = {
// healtcheck options

@@ -38,4 +54,5 @@ healthChecks: {

// cleanup options
timeout: 1000, // [optional = 5000] number of milliseconds before forcefull exiting
timeout: 1000, // [optional = 1000] number of milliseconds before forcefull exiting
signal, // [optional = 'SIGTERM'] what signal to listen for relative to shutdown
beforeShutdown, // [optional] called before the HTTP server starts its shutdown
onSignal, // [optional] cleanup function, returning a promise (used to be onSigterm)

@@ -45,6 +62,8 @@ onShutdown, // [optional] called right before exiting

// both
logger // [optional] logger function to be called with errors
});
logger // [optional] logger function to be called with errors
};
server.listen(PORT);
terminus(server, options);
server.listen(PORT || 3000);
```

@@ -64,7 +83,9 @@

terminus(server, {
const options = {
// opts
});
};
server.listen(3000);
terminus(server, options);
server.listen(PORT || 3000);
```

@@ -81,7 +102,17 @@

terminus(server, {
//opts
});
const options = {
// opts
};
server.listen(3000);
terminus(server, options);
server.listen(PORT || 3000);
```
## Limited Windows support
Due to inherent platform limitations, `terminus` has limited support for Windows.
You can expect `SIGINT` to work, as well as `SIGBREAK` and to some extent `SIGHUP`.
However `SIGTERM` will never work on Windows because killing a process in the task manager is unconditional, i.e., there's no way for an application to detect or prevent it.
Here's some relevant documentation from [`libuv`](https://github.com/libuv/libuv) to learn more about what `SIGINT`, `SIGBREAK` etc. signify and what's supported on Windows - http://docs.libuv.org/en/v1.x/signal.html.
Also see https://nodejs.org/api/process.html#process_signal_events.

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