### Minimal Fastify setup with graceful exit Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md A basic example demonstrating the minimal setup for Fastify with the graceful exit plugin enabled. This setup handles graceful exits on common signals. ```typescript import createFastify from "fastify"; import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; const fastify = createFastify({ disableRequestLogging: true }); await fastify.register(fastifyGracefulExit); await fastify.listen({ port: 3000 }); console.log("Server running on port 3000"); // Graceful exit on SIGTERM, SIGINT, SIGUSR2, or unhandled errors ``` -------------------------------- ### Full Server Initialization with Graceful Exit Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/API_INDEX.md Demonstrates a complete server setup, including Fastify initialization with custom logger settings, registration of the graceful exit plugin with detailed log bindings, and starting the server. Ensure to handle potential errors during server startup. ```typescript async function startServer() { const fastify = createFastify({ logger: { level: process.env.LOG_LEVEL || "info" }, disableRequestLogging: true }); await fastify.register(fastifyGracefulExit, { timeout: 10000, logBindings: { service: process.env.SERVICE_NAME, environment: process.env.NODE_ENV, version: process.env.BUILD_VERSION } }); await fastify.listen({ port: 3000 }); console.log("Server running"); } startServer().catch(fastify.log.error); ``` -------------------------------- ### Full Fastify setup with graceful exit configuration Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md An example showing a full setup with custom configuration for the graceful exit plugin, including timeout and log bindings. This allows for more control over the shutdown process. ```typescript import createFastify from "fastify"; import fastifyGracefulExit, { FastifyGracefulExitOptions } from "@mgcrea/fastify-graceful-exit"; const fastify = createFastify({ disableRequestLogging: true, logger: { level: process.env.LOG_LEVEL || "info" } }); const gracefulExitOptions: FastifyGracefulExitOptions = { timeout: 10000, logBindings: { service: "api-server", environment: process.env.NODE_ENV || "development", version: process.env.BUILD_VERSION || "1.0.0" } }; await fastify.register(fastifyGracefulExit, gracefulExitOptions); await fastify.listen({ port: 3000 }); ``` -------------------------------- ### Start Fastify Server Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/LIFECYCLE.md Listen on the specified port to start accepting connections. The graceful exit handlers remain active and armed after this step. ```typescript await fastify.listen({ port: 3000 }); ``` -------------------------------- ### Install Fastify GracefulExit Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/README.md Install the plugin and its peer dependency, fastify-cookie, using npm or pnpm. ```bash npm install fastify-cookie @mgcrea/fastify-graceful-exit --save # or pnpm add fastify-cookie @mgcrea/fastify-graceful-exit ``` -------------------------------- ### Install fastify-graceful-exit Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/API_INDEX.md Install the package using npm. ```bash npm install @mgcrea/fastify-graceful-exit ``` -------------------------------- ### Install fastify-graceful-exit with npm, pnpm, or yarn Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md Install the package using your preferred Node.js package manager. ```bash npm install @mgcrea/fastify-graceful-exit # or pnpm add @mgcrea/fastify-graceful-exit # or yarn add @mgcrea/fastify-graceful-exit ``` -------------------------------- ### Graceful Shutdown Log Example Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Example of a log entry generated at WARN level during a graceful shutdown. This helps distinguish normal restarts from actual errors and prevents monitoring alerts. ```json { "level": 30, "levelLabel": "WARN", "msg": "Fastify is gracefully closing from signal=\"SIGTERM\" ..." } ``` -------------------------------- ### Handler Reentrance Example Timeline Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/LIFECYCLE.md Demonstrates how the plugin handles multiple signals received in quick succession, ensuring only one shutdown process runs. ```text T+0ms: SIGTERM received → gracefullyClose("SIGTERM") called T+1ms: Log warning message, schedule timeout, call fastify.close() T+2ms: SIGINT received → gracefullyClose("SIGINT") called T+2ms: Detects closePromise is not null, returns existing promise (no new logging, no new timeout, returns same promise) T+5ms: fastify.close() resolves T+6ms: process.exit(0) called T+6ms: Both signal handlers have completed, process terminates ``` -------------------------------- ### Registering the Plugin with Fastify Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/api-reference/default-export.md Standard Fastify plugin registration using fastify.register(). Includes example options for timeout and logBindings. ```typescript import createFastify from "fastify"; import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; const fastify = createFastify(); await fastify.register(fastifyGracefulExit, { timeout: 3000, logBindings: { plugin: "fastify-graceful-exit" } }); ``` -------------------------------- ### Fastify Graceful Exit Log Bindings Example Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/configuration.md Demonstrates how log bindings are passed to Fastify's logger for contextual data during graceful shutdown or uncaught exceptions. Ensure Fastify's logger is configured to accept these bindings. ```typescript log.warn(logBindings, "Fastify is gracefully closing from signal=\"SIGTERM\" ..."); log.error({ err }, "Uncaught Exception: ..."); ``` -------------------------------- ### Test Timeout Behavior with Process Termination Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md This bash script demonstrates how to test application timeout behavior by starting a Fastify server, sending a slow request, and then terminating the Node.js process during the request. Check logs to verify timeout handling. ```bash # Terminal 1 npm start # Terminal 2 curl -X POST http://localhost:3000/slow & sleep 1 kill -SIGTERM $(pgrep node) ``` -------------------------------- ### Register Fastify Graceful Exit Plugin (Minimal) Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/API_INDEX.md Register the fastify-graceful-exit plugin with default options. This is a basic setup for graceful shutdown. ```typescript const fastify = createFastify(); await fastify.register(fastifyGracefulExit); await fastify.listen({ port: 3000 }); ``` -------------------------------- ### Registering Fastify Graceful Exit with Options Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/types.md Example of how to register the fastify-graceful-exit plugin with custom options for timeout and logBindings. Ensure the plugin is imported correctly. ```typescript import fastifyGracefulExit, { FastifyGracefulExitOptions } from "@mgcrea/fastify-graceful-exit"; const options: FastifyGracefulExitOptions = { timeout: 5000, logBindings: { plugin: "fastify-graceful-exit", environment: "production", service: "api-server", version: "1.0.0" } }; await fastify.register(fastifyGracefulExit, options); ``` -------------------------------- ### Plugin Registration within a Factory Function Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/api-reference/default-export.md Illustrates registering the plugin within a Fastify factory function, allowing for encapsulated setup. ```typescript import createFastify, { FastifyServerOptions } from "fastify"; import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; export function buildFastify(options: FastifyServerOptions = {}) { const fastify = createFastify({ disableRequestLogging: true, ...options }); fastify.register(fastifyGracefulExit, { timeout: 3000, logBindings: { plugin: "fastify-graceful-exit" } }); return fastify; } const fastify = buildFastify(); await fastify.listen({ port: 3000 }); // Graceful exit is now enabled ``` -------------------------------- ### Register fastify-graceful-exit plugin with Fastify Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md Register the default export of the plugin with your Fastify instance. This is the minimal setup required. ```typescript await fastify.register(fastifyGracefulExit); ``` -------------------------------- ### Registering with Application Factory Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md Integrate fastify-graceful-exit when creating a Fastify app using an application factory function. This pattern helps in centralizing app setup and plugin registration. ```typescript import createFastify, { FastifyServerOptions } from "fastify"; import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; export function createApp(options: FastifyServerOptions = {}) { const fastify = createFastify({ disableRequestLogging: true, ...options }); // Register plugins fastify.register(fastifyGracefulExit, { timeout: 5000, logBindings: { plugin: "fastify-graceful-exit" } }); // Register routes fastify.get("/health", (request, reply) => { reply.send({ status: "ok" }); }); return fastify; } // Usage const app = createApp(); await app.listen({ port: 3000 }); ``` -------------------------------- ### Initiate Fastify Server Close Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/LIFECYCLE.md Starts the process of closing the Fastify server. This stops new connections, closes the listening socket, and waits for in-flight requests to complete. ```typescript closePromise = fastify.close(); ``` -------------------------------- ### Example Prometheus Metrics for Graceful Exit Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Illustrative Prometheus metrics for tracking graceful shutdown events, including total shutdowns by reason, duration for successful shutdowns, and the count of timeout incidents. ```prometheus # In application code (pseudo-code) fastify-graceful-exit_shutdown_total{reason="sigterm"} 1 fastify-graceful-exit_shutdown_duration_ms{status="success"} 245 fastify-graceful-exit_shutdown_timeout_total 0 ``` -------------------------------- ### Create Fastify Instance Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/LIFECYCLE.md Instantiate a Fastify server. At this stage, the graceful exit plugin is not yet registered and no handlers are active. ```typescript const fastify = createFastify({ disableRequestLogging: true }); ``` -------------------------------- ### systemd Service Configuration Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Configure a systemd service unit with Type=simple, Restart=on-failure, and TimeoutStopSec for graceful termination. ```ini [Service] Type=simple ExecStart=/usr/bin/node /opt/app/server.js Restart=on-failure RestartSec=5 TimeoutStopSec=30 # Service termination grace period [Install] WantedBy=multi-user.target ``` -------------------------------- ### Plugin Registration with Custom Configuration Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/api-reference/default-export.md Shows how to register the plugin with custom timeout and logBindings for more specific logging. ```typescript await fastify.register(fastifyGracefulExit, { timeout: 5000, logBindings: { plugin: "fastify-graceful-exit", environment: "production", service: "user-api" } }); ``` -------------------------------- ### Inspecting Pod Status in Kubernetes Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/LIFECYCLE.md In Kubernetes, you can check the STATUS column of the `kubectl get pods` output to see if a pod has crashed and its exit code. ```bash kubectl get pods # STATUS shows exit code if crashed ``` -------------------------------- ### Kubernetes Shutdown Flow Timeline Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Illustrates the sequence of events during a Kubernetes pod termination, from SIGTERM to process exit, highlighting the plugin's role and the importance of timing. ```text T+0s: kubectl delete pod T+0s: Kubernetes sends SIGTERM to container T+0s: preStop hook executes (if configured, e.g., sleep 5s) T+5s: preStop hook completes T+5s: Plugin receives SIGTERM (if preStop used, window narrows) T+5s: Plugin logs warning, starts timeout (15s) T+5s: fastify.close() called T+15s: fastify.close() completes (all requests drained) T+15s: process.exit(0) called T+15s: Container exits with code 0 T+30s: Kubernetes sends SIGKILL to any remaining process (plugin already exited, this is a no-op) Best Practice: Set plugin timeout to 50-70% of `terminationGracePeriodSeconds`: - If grace period is 30s → plugin timeout should be 15-20s - If grace period is 60s → plugin timeout should be 30-40s ``` -------------------------------- ### Fastify Plugin Configuration for systemd Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Register the fastify-graceful-exit plugin with a timeout less than the systemd TimeoutStopSec and define service-specific log bindings. ```typescript await fastify.register(fastifyGracefulExit, { timeout: 15000, // Less than TimeoutStopSec logBindings: { service: "api-server", environment: "production" } }); ``` -------------------------------- ### Environment-Based Configuration Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md Configure fastify-graceful-exit dynamically based on environment variables. This allows for different timeout or logging configurations for production versus development environments. ```typescript function getGracefulExitConfig() { const env = process.env.NODE_ENV || "development"; return { timeout: env === "production" ? 30000 : 3000, logBindings: { plugin: "fastify-graceful-exit", environment: env, service: process.env.SERVICE_NAME, hostname: process.env.HOSTNAME, region: process.env.AWS_REGION } }; } await fastify.register(fastifyGracefulExit, getGracefulExitConfig()); ``` -------------------------------- ### Measure Request Duration for Shutdown Timeout Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Log request start and end times to measure their duration. This is crucial for identifying if requests are exceeding the configured graceful shutdown timeout. ```typescript // Log request start/end to measure duration fastify.get("/slow", async (request, reply) => { const start = Date.now(); console.log("Request started"); await slowOperation(); // Measure this const duration = Date.now() - start; console.log(`Request completed in ${duration}ms`); reply.send({ duration }); }); // If requests take 5s but timeout is 3s, increase timeout ``` -------------------------------- ### Basic Plugin Registration Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/api-reference/default-export.md Demonstrates the most basic way to register the fastifyGracefulExit plugin with a Fastify instance. ```typescript import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; const fastify = createFastify({ disableRequestLogging: true }); await fastify.register(fastifyGracefulExit); await fastify.listen({ port: 3000 }); ``` -------------------------------- ### Entry Point Exports Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/ARCHITECTURE.md Defines the exports from the main entry point file, including types and the default plugin export. ```typescript export type { FastifyGracefulExitOptions } from "./plugin"; export default fastifyPlugin(plugin, {...}); ``` -------------------------------- ### Import Configuration Type Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/SUMMARY.md Import the type definition for plugin configuration options. ```typescript import type { FastifyGracefulExitOptions } from "@mgcrea/fastify-graceful-exit"; ``` -------------------------------- ### Fastify Plugin Configuration for Kubernetes Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Register the fastify-graceful-exit plugin with a timeout less than the Kubernetes termination grace period and define log bindings for production environments. ```typescript import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; await fastify.register(fastifyGracefulExit, { timeout: 15000, // Must be less than terminationGracePeriodSeconds (30s) logBindings: { plugin: "fastify-graceful-exit", environment: "production", service: process.env.SERVICE_NAME, deployment: process.env.DEPLOYMENT_NAME, namespace: process.env.NAMESPACE, pod: process.env.POD_NAME } }); ``` -------------------------------- ### Correct Fastify Graceful Exit Import Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md Import the plugin using the correct namespace path to ensure it resolves properly within your project. ```typescript // ✓ Correct import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; // ✗ Incorrect (would fail to resolve) import fastifyGracefulExit from "fastify-graceful-exit"; ``` -------------------------------- ### CommonJS Import for fastify-graceful-exit Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md Import the plugin using the CommonJS `require` syntax. ```javascript const fastifyGracefulExit = require("@mgcrea/fastify-graceful-exit").default; ``` -------------------------------- ### Fastify Plugin Configuration for Docker Compose Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Register the fastify-graceful-exit plugin with a timeout less than the Docker Compose stop_grace_period and define relevant log bindings. ```typescript await fastify.register(fastifyGracefulExit, { timeout: 20000, // Less than stop_grace_period (30s) logBindings: { environment: "production", service: "api", region: process.env.AWS_REGION } }); ``` -------------------------------- ### Initial State Before Registration Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/LIFECYCLE.md Represents the state of lifecycle management before any Fastify registration occurs. `closePromise` is undefined and `signalHandlers` are not yet configured. ```typescript { closePromise: undefined, // Not defined yet signalHandlers: undefined } ``` -------------------------------- ### State After Registration, Before Shutdown Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/LIFECYCLE.md Illustrates the state after Fastify registration but before a shutdown is initiated. `closePromise` is initialized to null, and signal handlers are registered on the process. ```typescript { closePromise: null, // Initialized to null signalHandlers: [ { signal: "SIGTERM", fn: gracefullyClose }, { signal: "SIGINT", fn: gracefullyClose }, { signal: "SIGUSR2", fn: gracefullyClose }, { event: "uncaughtException", fn: ...}, { event: "unhandledRejection", fn: ...} ] } ``` -------------------------------- ### Kubernetes Deployment Configuration Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Configure Kubernetes deployment with a termination grace period and an optional preStop hook for draining connections before the plugin receives SIGTERM. ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: api-server spec: template: spec: terminationGracePeriodSeconds: 30 # Container grace period containers: - name: app image: myapp:latest lifecycle: preStop: exec: command: ["/bin/sh", "-c", "sleep 5"] # Optional drain delay ``` -------------------------------- ### Create App with Graceful Exit Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/API_INDEX.md Use this factory pattern to create a Fastify application instance and automatically register the graceful exit plugin with a default timeout and log bindings. ```typescript export function createApp(options = {}) { const fastify = createFastify({ disableRequestLogging: true, ...options }); fastify.register(fastifyGracefulExit, { timeout: 5000, logBindings: { plugin: "graceful-exit" } }); return fastify; } ``` -------------------------------- ### Manual Signal Testing Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/SUMMARY.md Simulates a SIGTERM signal to test the graceful shutdown process. This is useful for manual verification in development environments. ```javascript process.kill(process.pid, "SIGTERM") ``` -------------------------------- ### Minimal Fastify Graceful Exit Configuration Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/configuration.md Registers the plugin with default timeout and log bindings. Ensure the plugin is imported. ```typescript import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; await fastify.register(fastifyGracefulExit); ``` -------------------------------- ### Register fastify-graceful-exit Plugin Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/LIFECYCLE.md Register the plugin with Fastify, providing configuration options like timeout and log bindings. This step attaches process signal and exception handlers. ```typescript await fastify.register(fastifyGracefulExit, { timeout: 3000, logBindings: { plugin: "fastify-graceful-exit" } }); ``` -------------------------------- ### Docker Compose Configuration Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Configure Docker Compose with a stop_grace_period and set environment variables for production. ```yaml version: '3.8' services: api: image: myapp:latest stop_grace_period: 30s # Container grace period environment: - LOG_LEVEL=info - NODE_ENV=production ``` -------------------------------- ### Registering Fastify Graceful Exit with Log Bindings Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Register the fastify-graceful-exit plugin and configure custom log bindings for better log correlation across multiple processes. This includes service name, version, instance ID, hostname, and environment. ```typescript await fastify.register(fastifyGracefulExit, { logBindings: { plugin: "fastify-graceful-exit", service: process.env.SERVICE_NAME, version: process.env.BUILD_VERSION, instance_id: process.env.INSTANCE_ID, hostname: os.hostname(), environment: process.env.NODE_ENV } }); ``` -------------------------------- ### ES Module Import for fastify-graceful-exit Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md Recommended method for importing the plugin and its types in ES Module environments. ```typescript import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; import type { FastifyGracefulExitOptions } from "@mgcrea/fastify-graceful-exit"; ``` -------------------------------- ### Normal Graceful Shutdown Timeline Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/LIFECYCLE.md Illustrates the sequence of events during a standard graceful shutdown triggered by a SIGTERM signal. ```text T+0ms: SIGTERM received T+1ms: Log "Fastify is gracefully closing..." T+2ms: Timeout scheduled for T+3002ms T+3ms: fastify.close() called T+3ms: Start waiting for in-flight requests T+150ms: All in-flight requests complete T+151ms: fastify.close() resolves T+151ms: process.exit(0) called T+151ms: Process terminates with exit code 0 ``` -------------------------------- ### Fastify Graceful Exit with Custom Configuration Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/API_INDEX.md Configure the fastify-graceful-exit plugin with a custom shutdown timeout and logging bindings. This allows for tailored shutdown behavior and integrated logging. ```typescript import fastifyGracefulExit, { FastifyGracefulExitOptions } from "@mgcrea/fastify-graceful-exit"; const options: FastifyGracefulExitOptions = { timeout: 10000, logBindings: { service: "api", environment: "production" } }; await fastify.register(fastifyGracefulExit, options); ``` -------------------------------- ### FastifyGracefulExitOptions Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/types.md Configuration object for the fastify-graceful-exit plugin. This object is passed as the second argument to `fastify.register()` to customize the plugin's behavior. ```APIDOC ## FastifyGracefulExitOptions ### Description Configuration object for the fastify-graceful-exit plugin. Passed as the second argument to `fastify.register()`. ### Type Definition ```typescript export type FastifyGracefulExitOptions = { logBindings?: Record; timeout?: number; }; ``` ### Properties #### logBindings - **logBindings** (Record) - Optional - Additional fields to include in log messages. Standard Fastify logging context. Can include service name, environment, version, or any other metadata. Defaults to `{ plugin: "fastify-graceful-exit" }`. #### timeout - **timeout** (number) - Optional - Maximum milliseconds to wait for graceful shutdown before forcing process exit with code 1. If the server does not close within this window, the process is terminated. Defaults to `3000`. ### Usage Example ```typescript import fastifyGracefulExit, { FastifyGracefulExitOptions } from "@mgcrea/fastify-graceful-exit"; const options: FastifyGracefulExitOptions = { timeout: 5000, logBindings: { plugin: "fastify-graceful-exit", environment: "production", service: "api-server", version: "1.0.0" } }; await fastify.register(fastifyGracefulExit, options); ``` ``` -------------------------------- ### Default Options for Fastify Graceful Exit Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/types.md Illustrates the default values for logBindings and timeout when no options are explicitly provided to the fastify-graceful-exit plugin. These defaults ensure a basic level of graceful shutdown. ```typescript const defaults = { logBindings: { plugin: "fastify-graceful-exit" }, timeout: 3000 }; ``` -------------------------------- ### Graceful Close Initiated Log Format Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/errors.md This JSON structure represents the log format when a graceful close is initiated by a signal. It includes the warning level, the plugin name, and the signal that triggered the closure. ```json { "level": "warn", "plugin": "fastify-graceful-exit", "msg": "Fastify is gracefully closing from signal=\"SIGTERM\" ..." } ``` -------------------------------- ### Fastify Graceful Exit with Development Logging Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/configuration.md Registers the plugin with a shorter timeout and development-specific log bindings, including a debug flag. This aids in faster iteration during development. ```typescript await fastify.register(fastifyGracefulExit, { timeout: 1000, // Shorter timeout for faster development iteration logBindings: { plugin: "fastify-graceful-exit", environment: "development", debug: true } }); ``` -------------------------------- ### Import Fastify Graceful Exit Module Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md Import the module without side effects. Signal handlers are only attached after the plugin is explicitly registered with a Fastify instance. ```typescript import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; // At this point: nothing is registered, no signal handlers attached const fastify = createFastify(); await fastify.register(fastifyGracefulExit); // Only after register(): signal handlers are attached ``` -------------------------------- ### Graceful Shutdown Success Rate Calculation Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Pseudo-code for calculating the graceful shutdown success rate by counting warn logs indicating a graceful close versus those indicating a timeout. ```typescript // Count warn logs with "gracefully closing" // Count warn logs with "before timeout" // success_rate = closing_count / (closing_count + timeout_count) ``` -------------------------------- ### Fastify Graceful Exit with Production Logging Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/configuration.md Registers the plugin with a custom timeout and detailed production log bindings. This is useful for monitoring and debugging in production environments. ```typescript await fastify.register(fastifyGracefulExit, { timeout: 10000, logBindings: { plugin: "fastify-graceful-exit", environment: "production", service: "checkout-api", version: "2.1.0", region: "us-west-2", dataCenter: "aws-pdx" } }); ``` -------------------------------- ### Plugin Registration Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/API_INDEX.md This section describes how to register the fastify-graceful-exit plugin with your Fastify application. It includes the function signature, parameter details, and return value. ```APIDOC ## Plugin Registration ### Signature ```typescript fastify.register( fastifyGracefulExit, options?: FastifyGracefulExitOptions ): Promise ``` ### Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fastifyGracefulExit | FastifyPluginAsync | Yes | — | The plugin function | | options.timeout | number | No | 3000 | Milliseconds to wait before force-exiting | | options.logBindings | Record | No | { plugin: "fastify-graceful-exit" } | Additional context for logging | ### Returns `Promise` — Resolves when plugin is registered ### Minimal Example ```typescript const fastify = createFastify(); await fastify.register(fastifyGracefulExit); await fastify.listen({ port: 3000 }); ``` ### Full Example ```typescript const fastify = createFastify({ disableRequestLogging: true }); await fastify.register(fastifyGracefulExit, { timeout: 5000, logBindings: { service: "api-server", environment: "production", version: "1.0.0" } }); await fastify.listen({ port: 3000 }); ``` ``` -------------------------------- ### Error Handling with Decorators Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md Leverage fastify-graceful-exit for automatic graceful shutdown on unhandled errors or rejections within route handlers. No explicit top-level try-catch blocks are needed for these cases. ```typescript // After registering fastifyGracefulExit, your app can rely on graceful exit // for all unhandled errors. No additional try-catch needed at top level. fastify.get("/api/data", async (request, reply) => { // Any unhandled exception here → graceful exit const data = await fetchData(); reply.send(data); }); fastify.post("/api/process", async (request, reply) => { // Any unhandled rejection here → graceful exit await someAsyncTask(); reply.send({ success: true }); }); ``` -------------------------------- ### Register Fastify Graceful Exit Plugin Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/README.md Register the plugin with Fastify, optionally configuring the shutdown timeout. The default timeout is 3000ms. ```typescript import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; const fastify = createFastify(); await fastify.register(fastifyGracefulExit, { timeout: 3000 }); await fastify.listen({ port: 3000 }); ``` -------------------------------- ### Log Message for Graceful Shutdown Initiation Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/LIFECYCLE.md This JSON log pattern indicates that Fastify has successfully initiated a graceful shutdown sequence, typically triggered by a process signal. ```json { "msg": "Fastify is gracefully closing from signal=\"SIGTERM\" ...", "level": 30 // warn level } ``` -------------------------------- ### Registering with Plugin Chain Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md Register fastify-graceful-exit along with other plugins in a sequential plugin chain. Ensure it's registered after any plugins that might need to be shut down gracefully. ```typescript import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; import fastifySession from "@mgcrea/fastify-session"; import fastifyCompress from "@fastify/compress"; const fastify = createFastify({ disableRequestLogging: true }); // Register multiple plugins await fastify.register(fastifyCompress); await fastify.register(fastifySession, { /* options */ }); await fastify.register(fastifyGracefulExit, { timeout: 5000 }); await fastify.listen({ port: 3000 }); ``` -------------------------------- ### Inspecting Container State in Docker Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/LIFECYCLE.md For Docker containers, the `docker inspect` command can be used to retrieve detailed information, including the `ExitCode` within the `State` section. ```bash docker inspect CONTAINER # ExitCode in State section ``` -------------------------------- ### Fastify Graceful Exit Multi-Environment Factory Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/configuration.md A factory function to generate configuration for fastify-graceful-exit based on the environment. It sets different timeouts and log bindings for production, staging, and development. ```typescript import fastifyGracefulExit, { FastifyGracefulExitOptions } from "@mgcrea/fastify-graceful-exit"; function getGracefulExitConfig(env: string): FastifyGracefulExitOptions { const baseConfig: FastifyGracefulExitOptions = { logBindings: { plugin: "fastify-graceful-exit", environment: env, service: process.env.SERVICE_NAME || "api", version: process.env.BUILD_VERSION || "unknown" } }; if (env === "production") { return { ...baseConfig, timeout: 30000 }; // 30s for production } else if (env === "staging") { return { ...baseConfig, timeout: 15000 }; // 15s for staging } else { return { ...baseConfig, timeout: 3000 }; // 3s for development } } const fastify = createFastify(); const gracefulExitConfig = getGracefulExitConfig(process.env.NODE_ENV || "development"); await fastify.register(fastifyGracefulExit, gracefulExitConfig); ``` -------------------------------- ### Import Default Export Plugin Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/SUMMARY.md Import the main plugin function for use in your Fastify application. ```typescript import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; ``` -------------------------------- ### Production Dependencies for Fastify Plugin Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/ARCHITECTURE.md Specifies the 'fastify-plugin' as a production dependency, essential for integrating the plugin within the Fastify ecosystem. ```json { "fastify-plugin": "^5.0.1" } ``` -------------------------------- ### Register Fastify Graceful Exit Plugin Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/IMPORT_GUIDE.md Register the plugin with Fastify version 4 or later. Earlier versions will cause registration to fail. ```typescript import fastify from "fastify"; import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; // ✓ Fastify 4+ (plugin will register successfully) const fastify = createFastify({ ... }); await fastify.register(fastifyGracefulExit); // ✗ Fastify 3 or earlier (plugin will reject) // Registration will throw an error ``` -------------------------------- ### Registering FastifyGracefulExit Plugin Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/api-reference/fastify-graceful-exit-plugin.md Register the plugin with default options or provide custom timeout and log bindings for enhanced control over the graceful shutdown process. ```typescript import createFastify from "fastify"; import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; const fastify = createFastify({ disableRequestLogging: true }); // Register with default options (3000ms timeout) await fastify.register(fastifyGracefulExit); // Or register with custom timeout await fastify.register(fastifyGracefulExit, { timeout: 5000, logBindings: { service: "api-server", environment: "production" } }); await fastify.listen({ port: 3000 }); // Process will now gracefully shutdown on SIGTERM, SIGINT, SIGUSR2, or unhandled errors ``` -------------------------------- ### Monitor Close Operations and Event Loop Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Log the time taken for graceful closing operations and check Fastify's onClose hook. This helps identify resource leaks or event loop blocking that delays shutdown. ```typescript // Monitor what's causing slowness let closingStartTime; const gracefullyClose = async (signal: string) => { closingStartTime = Date.now(); // ... graceful close logic const closeTime = Date.now() - closingStartTime; console.log(`Close took ${closeTime}ms`); }; // Check database connection status fastify.addHook("onClose", async () => { console.log("Fastify close hook called"); }); // Verify all connections are closing ``` -------------------------------- ### Timeout-Triggered Shutdown Timeline Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/LIFECYCLE.md Shows the events when a graceful shutdown exceeds the configured timeout, leading to an abnormal exit. ```text T+0ms: SIGTERM received T+1ms: Log "Fastify is gracefully closing..." T+2ms: Timeout scheduled for T+3002ms T+3ms: fastify.close() called T+3ms: Start waiting for in-flight requests T+1000ms: Slow request still in progress (e.g., database query) T+3002ms: Timeout fires T+3003ms: Log "Failed to gracefully close before timeout" T+3004ms: process.exit(1) called T+3004ms: Process terminates with exit code 1 (slow request is interrupted, no cleanup possible) ``` -------------------------------- ### Simulate Slow Requests in Fastify Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md This TypeScript snippet simulates a slow HTTP POST request that takes 8 seconds to process. It's useful for testing how different timeout configurations handle long-running requests. ```typescript fastify.post("/slow", async (request, reply) => { await new Promise(resolve => setTimeout(resolve, 8000)); // 8 second request reply.send({ processed: true }); }); ``` -------------------------------- ### Fastify Graceful Exit Options Schema Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/configuration.md Defines the TypeScript interface for the configuration object accepted by the fastify-graceful-exit plugin. Use this to type your configuration object. ```typescript type FastifyGracefulExitOptions = { logBindings?: Record; timeout?: number; }; ``` -------------------------------- ### Register Fastify GracefulExit Plugin Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/README.md Register the fastifyGracefulExit plugin with Fastify, optionally disabling request logging and setting a timeout for graceful shutdown. ```typescript import createFastify, { FastifyInstance, FastifyServerOptions } from "fastify"; import fastifyGracefulExit from "@mgcrea/fastify-graceful-exit"; export const buildFastify = (options: FastifyServerOptions = {}): FastifyInstance => { const fastify = createFastify({ disableRequestLogging: true, ...options }); fastify.register(fastifyGracefulExit, { timeout: 3000 }); return fastify; }; ``` -------------------------------- ### Handle Unhandled Exceptions with Fastify Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md The plugin catches unhandled exceptions, logs them, and initiates a graceful shutdown. Do not rely on this for error recovery; implement explicit try-catch blocks for robust error handling. ```typescript fastify.get("/api/data", async (request, reply) => { throw new Error("Something failed"); // Not caught }); ``` ```typescript fastify.get("/api/data", async (request, reply) => { try { const data = await fetchData(); reply.send(data); } catch (err) { fastify.log.error(err, "Failed to fetch data"); reply.code(500).send({ error: "Internal server error" }); } }); ``` -------------------------------- ### Average Shutdown Duration Measurement Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/PRODUCTION_GUIDE.md Pseudo-code for measuring the average shutdown duration. This involves timing the interval between the 'gracefully closing' log and the process exit, ensuring it stays within the configured timeout. ```typescript // Measure time between "gracefully closing" and process exit log // Should typically be ; timeout?: number; }; ``` -------------------------------- ### Fastify Plugin Definition Source: https://github.com/mgcrea/fastify-graceful-exit/blob/master/_autodocs/ARCHITECTURE.md Standard Fastify plugin structure using fastifyPlugin. Specifies Fastify version compatibility and plugin name. ```typescript const plugin: FastifyPluginAsync = async ( fastify, options = {}, ): Promise => { // Initialization logic // Return void (or implicit undefined) }; export default fastifyPlugin(plugin, { fastify: ">=4", name: "fastify-graceful-exit" }); ```