{"id":18926836,"url":"https://github.com/ladjs/graceful","last_synced_at":"2025-05-06T21:40:34.639Z","repository":{"id":44931861,"uuid":"103077938","full_name":"ladjs/graceful","owner":"ladjs","description":"Gracefully exit HTTP servers (Express/Koa/Fastify/etc), databases (Mongo/Mongoose), Redis clients, Bree job schedulers, and custom handlers.","archived":false,"fork":false,"pushed_at":"2025-01-07T16:50:48.000Z","size":558,"stargazers_count":74,"open_issues_count":4,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-19T23:02:49.586Z","etag":null,"topics":["agenda","cancel","exception","exit","graceful","handler","jobs","koa","mongo","mongoose","process","rejection","uncaught","warning","warnings"],"latest_commit_sha":null,"homepage":"https://lad.js.org","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ladjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-11T01:57:31.000Z","updated_at":"2025-01-07T16:50:52.000Z","dependencies_parsed_at":"2024-06-18T15:43:06.108Z","dependency_job_id":null,"html_url":"https://github.com/ladjs/graceful","commit_stats":{"total_commits":54,"total_committers":5,"mean_commits":10.8,"dds":0.6666666666666667,"last_synced_commit":"a11ef41971d2282a71d9e030b51cdeb0a1cdfb82"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ladjs%2Fgraceful","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ladjs%2Fgraceful/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ladjs%2Fgraceful/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ladjs%2Fgraceful/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ladjs","download_url":"https://codeload.github.com/ladjs/graceful/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252775488,"owners_count":21802452,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agenda","cancel","exception","exit","graceful","handler","jobs","koa","mongo","mongoose","process","rejection","uncaught","warning","warnings"],"created_at":"2024-11-08T11:17:19.387Z","updated_at":"2025-05-06T21:40:34.584Z","avatar_url":"https://github.com/ladjs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [**@ladjs/graceful**](https://github.com/ladjs/graceful)\n\n[![build status](https://github.com/ladjs/graceful/actions/workflows/ci.yml/badge.svg)](https://github.com/ladjs/graceful/actions/workflows/ci.yml)\n[![code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)\n[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)\n[![made with lass](https://img.shields.io/badge/made_with-lass-95CC28.svg)](https://lass.js.org)\n[![license](https://img.shields.io/github/license/ladjs/graceful.svg)]()\n\n\u003e Gracefully exit HTTP servers (Express/Koa/Fastify/etc), databases (Mongo/Mongoose), Redis clients, [Bree][] job schedulers, and custom handlers.\n\n\n## Table of Contents\n\n* [Install](#install)\n* [Usage](#usage)\n  * [Express](#express)\n  * [Koa](#koa)\n  * [Fastify](#fastify)\n  * [Other](#other)\n* [Instance Options](#instance-options)\n* [Examples](#examples)\n* [Contributors](#contributors)\n* [License](#license)\n\n\n## Install\n\n[npm][]:\n\n```sh\nnpm install @ladjs/graceful\n```\n\n\n## Usage\n\nSee the [Express](#express), [Koa](#koa), [Fastify](#fastify), or [Other](#other) code snippet examples and [Instance Options](#instance-options) below.\n\n**You can pass [Instance Options](#instance-options) to customize your graceful handler** (e.g. if you have more than one server, or wish to close both a Redis connection and a server at the same time).\n\n```js\nconst Graceful = require('@ladjs/graceful');\n\n//\n// ...\n//\n\n//\n// see Instance Options in the README below and examples for different projects (e.g. Koa or Express)\n//\nconst graceful = new Graceful({\n  //\n  // http or net servers\n  // (this supports Express/Koa/Fastify/etc)\n  // (basically anything created with http.createServer or net.createServer)\n  // \u003chttps://github.com/expressjs/express\u003e\n  // \u003chttps://github.com/koajs/koa\u003e\n  // \u003chttps://github.com/fastify/fastify\u003e\n  //\n  servers: [],\n\n  // bree clients\n  // \u003chttps://github.com/breejs/bree\u003e\n  brees: [],\n\n  // redis clients\n  // \u003chttps://github.com/luin/ioredis\u003e\n  // \u003chttps://github.com/redis/node-redis\u003e\n  redisClients: [],\n\n  // mongoose clients\n  // \u003chttps://github.com/Automattic/mongoose\u003e\n  mongooses: [],\n\n  // custom handlers to invoke upon shutdown\n  customHandlers: [],\n\n  // logger\n  logger: console,\n\n  // how long to wait in ms for exit to finish\n  timeoutMs: 5000,\n\n  // options to pass to `lil-http-terminator` to override defaults\n  lilHttpTerminator: {},\n\n  //\n  // appends a `true` boolean value to a property of this name in the logger meta object\n  // (this is useful for Cabin/Axe as it will prevent a log from being created in MongoDB)\n  // (and instead of having a DB log created upon graceful exit, it will simply log to console)\n  // (defer to the Forward Email codebase, specifically the logger helper)\n  //\n  // NOTE: if you set this to `false` then this will be ignored and no meta property will be populated\n  //\n  ignoreHook: 'ignore_hook',\n\n  //\n  // appends a `true` boolean value to a property of this name in the logger meta object\n  // (this is useful for Cabin/Axe as it will prevent the meta object from being outputted to the logger)\n  //\n  hideMeta: 'hide_meta'\n});\n\n//\n// NOTE: YOU MUST INVOKE `graceful.listen()` IN ORDER FOR THIS TO WORK!\n//\ngraceful.listen();\n```\n\nUsing this package will bind process event listeners when `graceful.listen()` is called:\n\n* `process.on('warning')` - will output via `config.logger.warn`\n* `process.on('unhandledRejection')` - bubbles up to `uncaughtException` (will output via `config.logger.error` and `process.exit(1)` (*does not exit gracefully*)\n* `process.once('uncaughtException')` - will output via `config.logger.error` and `process.exit(1)` (*does not exit gracefully*)\n* `process.on('message')` - support Windows (e.g. signals not available) and listen for message of `shutdown` and then exit gracefully\n* `process.once('SIGTERM')` - will exit gracefully\n* `process.once('SIGHUP')` - will exit gracefully\n* `process.once('SIGINT')` - will exit gracefully\n\nThis package also prevents multiple process/SIG events from triggering multiple graceful exits. Only one graceful exit can occur at a time.\n\nFor `servers` passed, we use [lil-http-terminator][] under the hood.  Default configuration options can be overridden by passing a `lilHttpTerminator` configuration object.  See [index.js](index.js) for more insight.\n\n### Express\n\n```js\nconst express = require('express');\nconst Graceful = require('@ladjs/graceful');\n\nconst app = express();\nconst server = app.listen();\nconst graceful = new Graceful({ servers: [server] });\ngraceful.listen();\n```\n\n### Koa\n\n```js\nconst Koa = require('koa');\nconst Graceful = require('@ladjs/graceful');\n\nconst app = new Koa();\nconst server = app.listen();\nconst graceful = new Graceful({ servers: [server] });\ngraceful.listen();\n```\n\n### Fastify\n\n```js\nconst fastify = require('fastify');\nconst Graceful = require('@ladjs/graceful');\n\nconst app = fastify();\napp.listen();\n\n//\n// NOTE: @ladjs/graceful is smart and detects `app.server` automatically\n//\nconst graceful = new Graceful({ servers: [app] });\ngraceful.listen();\n```\n\n### Other\n\nThis package works with any server created with `http.createServer` or `net.createServer` (Node's internal HTTP and Net packages).\n\n**Please defer to the [test folder files](test/test.js) for example usage.**\n\n\n## Instance Options\n\nHere is the full list of options and their defaults.  See [index.js](index.js) for more insight if necessary.\n\n| Property            | Type                      | Default Value   | Description                                                                                                                                                                                                                                                                                                                                                                                             |\n| ------------------- | ------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `servers`           | Array                     | `[]`            | An array of HTTP or NET servers to gracefully close on exit                                                                                                                                                                                                                                                                                                                                             |\n| `brees`             | Array                     | `[]`            | An array of [Bree][] instances to gracefully exit                                                                                                                                                                                                                                                                                                                                                       |\n| `redisClients`      | Array                     | `[]`            | An array of Redis client instances to gracefully exit                                                                                                                                                                                                                                                                                                                                                   |\n| `mongooses`         | Array                     | `[]`            | An array of Mongoose connections to gracefully exit                                                                                                                                                                                                                                                                                                                                                     |\n| `customHandlers`    | Array                     | `[]`            | An array of functions (custom handlers) to invoke upon graceful exit                                                                                                                                                                                                                                                                                                                                    |\n| `logger`            | Object                    | `console`       | This is the default logger.  **We recommend using [Cabin][cabin]** instead of using `console` as your default logger.  Set this value to `false` to disable logging entirely (uses noop function)                                                                                                                                                                                                       |\n| `timeoutMs`         | Number                    | `5000`          | A number in milliseconds for how long to wait to gracefully exit                                                                                                                                                                                                                                                                                                                                        |\n| `lilHttpTerminator` | Object                    | `{}`            | An object of options to pass to `lil-http-terminator` to override default options provided                                                                                                                                                                                                                                                                                                              |\n| `ignoreHook`        | String or `false` Boolean | `\"ignore_hook\"` | Appends a `true` boolean property to a property with this value in logs, e.g. `console.log('graceful exiting', { ignore_hook: true });` which is useful for preventing logs from being written to a database in hooks (this is meant for usage with [Cabin][] and [Axe][] and made for [Forward Email][forward-email]).  If you pass a `false` value then this property will not get populated.         |\n| `hideMeta`          | String or `false` Boolean | `\"hide_meta\"`   | Appends a `true` boolean property to a property with this value in logs, e.g. `console.log('graceful exiting', { hide_meta: true });` which is useful for preventing metadata object from being invoked as the second argument (this is meant for usage with [Cabin][] and [Axe][] and made for [Forward Email][forward-email]). If you pass a `false` value then this property will not get populated. |\n\n\n## Examples\n\nYou can refer Forward Email for more complex usage:\n\n* API - \u003chttps://github.com/forwardemail/forwardemail.net/blob/master/api.js\u003e\n* Web - \u003chttps://github.com/forwardemail/forwardemail.net/blob/master/web.js\u003e\n* Bree - \u003chttps://github.com/forwardemail/forwardemail.net/blob/master/bree.js\u003e\n* Proxy - \u003chttps://github.com/forwardemail/forwardemail.net/blob/master/proxy.js\u003e\n\nAdditionally you can also refer to [Lad][] usage:\n\n* API - \u003chttps://github.com/ladjs/lad/blob/master/template/api.js\u003e\n* Web - \u003chttps://github.com/ladjs/lad/blob/master/template/web.js\u003e\n* Bree - \u003chttps://github.com/ladjs/lad/blob/master/template/bree.js\u003e\n* Proxy - \u003chttps://github.com/ladjs/lad/blob/master/template/proxy.js\u003e\n\nYou can also read more about Bree at \u003chttps://github.com/breejs/bree\u003e.\n\n\n## Contributors\n\n| Name                | Website                        |\n| ------------------- | ------------------------------ |\n| **Nick Baugh**      | \u003chttp://niftylettuce.com/\u003e     |\n| **Felix Mosheev**   | \u003chttps://github.com/felixmosh\u003e |\n| **Nicholai Nissen** | \u003chttps://nicholai.dev\u003e         |\n| **Spencer Snyder**  | \u003chttps://spencersnyder.io\u003e     |\n\n\n## License\n\n[MIT](LICENSE) © [Nick Baugh](http://niftylettuce.com/)\n\n\n##\n\n[npm]: https://www.npmjs.com/\n\n[lad]: https://lad.js.org\n\n[lil-http-terminator]: https://github.com/flash-oss/lil-http-terminator\n\n[cabin]: https://cabinjs.com\n\n[bree]: https://jobscheduler.net\n\n[axe]: https://github.com/cabinjs/axe\n\n[forward-email]: https://github.com/forwardemail\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fladjs%2Fgraceful","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fladjs%2Fgraceful","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fladjs%2Fgraceful/lists"}