Lifecycle & Graceful Shutdown
Lifecycle & Graceful Shutdown
Relevant source files
The following files were used as context for generating this wiki page:
The lifecycle module provides a centralized mechanism for managing the termination phase of a microservice. It ensures that when a process receives a termination signal or encounters an unrecoverable error, it performs all necessary cleanup tasks—such as closing database connections or disconnecting from NATS—before exiting with the appropriate status code.
The GracefulShutdown Class
The core of this module is the GracefulShutdown class src/lifecycle/graceful-shutdown.ts:16-59. It acts as a registry for cleanup logic and a manager for process-level events.
Key Components
| Component | Description |
|---|---|
shuttingDown | A boolean re-entrancy guard to ensure shutdown logic only runs once src/lifecycle/graceful-shutdown.ts:17. |
cleanups | An array of CleanupFn (asynchronous functions) to be executed during termination src/lifecycle/graceful-shutdown.ts:18. |
serviceName | A string identifier used for logging shutdown events src/lifecycle/graceful-shutdown.ts:19. |
Registration and Execution Flow
The following diagram illustrates how cleanup functions are registered and subsequently executed when a signal is received.
Lifecycle Management Flow
Code
Sources: src/lifecycle/graceful-shutdown.ts:16-59, src/lifecycle/tests/graceful-shutdown.test.ts:22-32
Signal Handling and Installation
The install() method src/lifecycle/graceful-shutdown.ts:31-47 configures the Node.js process to listen for specific termination signals and runtime errors.
Handled Events
- Standard Signals:
SIGTERM,SIGINT, andSIGHUPsrc/lifecycle/graceful-shutdown.ts:32.- The exit code is calculated as
128 + signal_constant(e.g.,SIGTERMusually results in143) src/lifecycle/graceful-shutdown.ts:35.
- The exit code is calculated as
- Uncaught Errors:
uncaughtExceptionandunhandledRejectionsrc/lifecycle/graceful-shutdown.ts:39-46.- These events log the error/reason to
stderrand trigger a shutdown with exit code1src/lifecycle/graceful-shutdown.ts:41,45.
- These events log the error/reason to
Signal to Code Mapping
Code
Sources: src/lifecycle/graceful-shutdown.ts:31-47, src/lifecycle/graceful-shutdown.ts:49-58
Implementation Details
Re-entrancy Guard
To prevent race conditions where multiple signals (e.g., a user hitting Ctrl+C twice) trigger multiple cleanup cycles, the shutdown method checks the shuttingDown flag src/lifecycle/graceful-shutdown.ts:50-51. If a shutdown is already in progress, subsequent calls return immediately.
Parallel Cleanup
Cleanup functions are executed in parallel using Promise.allSettled src/lifecycle/graceful-shutdown.ts:54. This ensures that:
- The shutdown process is as fast as possible.
- A failure in one cleanup function (e.g., a database connection timeout) does not prevent other cleanup functions from running.
Explicit Exit
The class always calls process.exit(code) within a finally block src/lifecycle/graceful-shutdown.ts:55-57. This ensures that even if the cleanup logic throws an error, the process will terminate with the intended status code.
Usage Example
Consumers typically initialize the lifecycle manager during the bootstrap phase of the application.
Code
Sources: src/lifecycle/graceful-shutdown.ts:16-59, src/lifecycle/tests/graceful-shutdown.test.ts:47-56