All Projects → kanongil → exiting

kanongil / exiting

Licence: BSD-2-Clause License
Safely shutdown http://hapijs.com servers.

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Labels

Projects that are alternatives of or similar to exiting

hapi-doorkeeper
User authentication for web servers
Stars: ✭ 14 (-39.13%)
Mutual labels:  hapi
hapi-react-fullstack-boilerplate
Hapi, Sequelize, React, etc.
Stars: ✭ 21 (-8.7%)
Mutual labels:  hapi
hapi-moon
Hassle-free and production ready hapi.js Server boilerplate
Stars: ✭ 23 (+0%)
Mutual labels:  hapi
noire-server
Hapi Boilerplate
Stars: ✭ 20 (-13.04%)
Mutual labels:  hapi
generator-hapi-plus
Hapi REST API generator with PostgreSql, MySql, Mongo plugins, automatic Swagger docs, authentication with JWT, logging, Docker etc
Stars: ✭ 21 (-8.7%)
Mutual labels:  hapi
wily
Build Node.js APIs from the command line (Dead Project 😵)
Stars: ✭ 14 (-39.13%)
Mutual labels:  hapi
hapi-good-winston
A good reporter to send and log events with winston
Stars: ✭ 21 (-8.7%)
Mutual labels:  hapi
hapi-sentry
A hapi plugin for request error logging to Sentry
Stars: ✭ 24 (+4.35%)
Mutual labels:  hapi
hapi-cli
CLI to build API with Hapi, mongodb and mongoose. Work with Hapi V17.
Stars: ✭ 36 (+56.52%)
Mutual labels:  hapi
hapi-auth-bearer-simple
Hapi authentication plugin for bearer token validation
Stars: ✭ 16 (-30.43%)
Mutual labels:  hapi
minimal-hapi-react-webpack
Minimal Hapi + React + Webpack + HMR (hot module reloading) Sandbox
Stars: ✭ 55 (+139.13%)
Mutual labels:  hapi
felicity
Javascript object constructors and sample data based on Joi schema.
Stars: ✭ 107 (+365.22%)
Mutual labels:  hapi
api.pokedextracker.com
API for pokedextracker.com
Stars: ✭ 38 (+65.22%)
Mutual labels:  hapi
hapi-mongo-models
📦 A hapi plugin for `mongo-models`
Stars: ✭ 101 (+339.13%)
Mutual labels:  hapi
steerage
Hapi server configuration and composition using confidence, topo, and shortstop.
Stars: ✭ 15 (-34.78%)
Mutual labels:  hapi
hapi-now-auth
Hapi token auth for bearer and jwt
Stars: ✭ 43 (+86.96%)
Mutual labels:  hapi
typesafe-hapi
Typechecking for HapiJS based on Joi schemas!
Stars: ✭ 21 (-8.7%)
Mutual labels:  hapi
Crashlyzer
Crash viewer web application for displaying the crashes reported by rn-crash-reporter components from React Native mobile applications.
Stars: ✭ 59 (+156.52%)
Mutual labels:  hapi
hapi-decorators
Decorators for HapiJS routes
Stars: ✭ 65 (+182.61%)
Mutual labels:  hapi
my-blog
node.js vue.js nuxt.js hapi.js mysql 仿简书博客
Stars: ✭ 25 (+8.7%)
Mutual labels:  hapi

Exiting

Safely shutdown hapi.js servers whenever the process exits.

Node.js CI

Details

While it is simple to start and stop a server, ensuring proper shutdown on external, or internal, triggers can be cumbersome to handle properly. exiting makes this easy by managing your Hapi servers, taking care of starting and stopping them as appropriate.

Depending on the exit trigger, the hapi servers will either be gracefully stopped or aborted (by only triggering onPreStop hooks). The exit triggers are handled as detailed:

  • Graceful exit with code 0:
    • process.exit() with exit code 0.
    • Unhandled SIGINT kill signal, through eg. ctrl-c.
    • Unhandled SIGTERM kill signal.
    • Unhandled SIGQUIT kill signal.
  • Aborted exit:
    • process.exit() with non-zero exit code.
    • Unhandled SIGHUP kill signal (code 1).
    • Any uncaught exception (code 1).
    • Any unhandled rejection (code 1).
    • Any closed connection listeners, eg. on worker disconnect (code 255).

If shutting down one of the servers is too slow, a timeout will eventually trigger an exit (exit code 255).

The shutdown logic is programmed to handle almost any conceivable exit condition, and provides 100% test coverage. The only instances that onPreHook code is not called, are uncatchable signals, like SIGKILL, and fatal errors that trigger during shutdown.

Example

Basic server example:

const Hapi = require('hapi');
const Exiting = require('exiting');

const server = Hapi.Server();
const manager = Exiting.createManager(server);

server.events.on('stop', () => {

    console.log('Server stopped.');
});

const provision = async () => {

    server.route({
        method: 'GET',
        path: '/',
        handler: () => 'Hello' 
    });

    await manager.start();

    console.log('Server started at:', server.info.uri);
};

provision();

The server and process life-cycle will now be managed by exiting.

If you need to delay the shutdown for processing, you can install an extention function on the onPreStop or onPostStop extension points, eg:

server.ext('onPreStop', () => {

    return new Promise((resolve) => {

        setTimeout(resolve, 1000);
    });
});

Multiple servers example:

const Hapi = require('hapi');
const Exiting = require('exiting');

const publicServer = Hapi.Server();
const adminServer = Hapi.Server();
const manager = Exiting.createManager([publicServer, adminServer]);

const provision = async () => {

    publicServer.route({
        method: 'GET',
        path: '/',
        handler: () => 'Hello'
    });

    adminServer.route({
        method: 'GET',
        path: '/',
        handler: () => 'Hello Admin'
    });

    await manager.start();

    console.log('Public server started at:', publicServer.info.uri);
    console.log('Admin server started at:', adminServer.info.uri);
};

provision();

Installation

Install using npm: npm install exiting.

Usage

To enable exiting for you server, replace the call to server.start() with Exiting.createManager(server).start().

Exiting.createManager(servers, [options])

Create a new exit manager for one or more hapi.js servers. The options object supports:

  • exitTimeout - When exiting, force process exit after this amount of ms has elapsed. Default: 5000.

await manager.start()

Starts the manager and all the managed servers, as if server.start() is called on each server. If any server fails to start, all will be stopped with server.stop() before the error is re-thrown.

Note that process.exit() is monkey patched to intercept such calls. Starting also installs the signal handlers and an uncaughtException handler.

await manager.stop([options])

Stops the manager and all the servers, as if server.stop() is called on each server.

Notes on process.exit()

The process.exit() method is handled in a special manner that allows the asyncronous stop logic to resolve before actually exiting. Since this can be called from anywhere in the code, and subsequent code is never expected to be executed, the manager will throw an Exiting.ProcessExitError to attempt to escape the current execution context. This allows something like the following to still exit:

while (true) {
    process.exit(1);
}

This might not always work, and can potentially cause a lock up instead of exiting. Eg. with this code:

try {
    process.exit(1);
}
catch (err) {
    /* do nothing */
}
while (true) {}

You should avoid using process.exit() in your own code, and call manager.stop() instead.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].