PrimebrickPrimebrick
  • Primebrick.dev
  • GitHub
  • Documentation
  • Services
  • Libraries
  • API Catalog
Resources
  • Landing Page
  • API Catalog
  • GitHub
PrimebrickPrimebrick

© 2026 Primebrick. MIT License.

github
DAL Library
SDK Library
    Architecture: Ports & AdaptersBuild, Tooling & CI/CDCI/CD & NPM PublishingConfiguration ManagementCore ModulesDatabase MigrationsEnvironment ValidationGetting StartedGlossaryHTTP Server & Health ChecksLifecycle & Graceful ShutdownModule Test PatternsNATS Messaging ClientOverviewService Registration & HeartbeatTest Infrastructure & ConfigurationTestingTypeScript Build ConfigurationREADME
powered by Zudoku
SDK Library

Lifecycle & Graceful Shutdown

Lifecycle & Graceful Shutdown

Relevant source files

The following files were used as context for generating this wiki page:

  • src/lifecycle/tests/graceful-shutdown.test.ts
  • src/lifecycle/graceful-shutdown.ts

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

ComponentDescription
shuttingDownA boolean re-entrancy guard to ensure shutdown logic only runs once src/lifecycle/graceful-shutdown.ts:17.
cleanupsAn array of CleanupFn (asynchronous functions) to be executed during termination src/lifecycle/graceful-shutdown.ts:18.
serviceNameA 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
sequenceDiagram participant App as "Consumer Application" participant GS as "GracefulShutdown Instance" participant Proc as "Node.js process" App->>GS: new GracefulShutdown("my-service") App->>GS: addCleanup(nats.close) App->>GS: addCleanup(db.close) App->>GS: install() GS->>Proc: on("SIGTERM", handler) GS->>Proc: on("uncaughtException", handler) Note over Proc: External SIGTERM received Proc->>GS: Trigger handler GS->>GS: Set shuttingDown = true par Parallel Cleanup GS->>App: 执行 nats.close() GS->>App: 执行 db.close() end GS->>Proc: exit(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

  1. Standard Signals: SIGTERM, SIGINT, and SIGHUP src/lifecycle/graceful-shutdown.ts:32.
    • The exit code is calculated as 128 + signal_constant (e.g., SIGTERM usually results in 143) src/lifecycle/graceful-shutdown.ts:35.
  2. Uncaught Errors: uncaughtException and unhandledRejection src/lifecycle/graceful-shutdown.ts:39-46.
    • These events log the error/reason to stderr and trigger a shutdown with exit code 1 src/lifecycle/graceful-shutdown.ts:41,45.

Signal to Code Mapping

Code
graph TD subgraph "Process Events" SIG["SIGTERM / SIGINT / SIGHUP"] ERR["uncaughtException / unhandledRejection"] end subgraph "GracefulShutdown.install()" Handler["shutdown(reason, code)"] end SIG -->| "code = 128 + signal" | Handler ERR -->| "code = 1" | Handler Handler -->| "Promise.allSettled" | Cleanup["cleanups[]"] Cleanup --> Exit["process.exit(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:

  1. The shutdown process is as fast as possible.
  2. 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
import { GracefulShutdown } from '@primebrick/sdk'; const lifecycle = new GracefulShutdown("order-service"); // Register cleanup tasks lifecycle.addCleanup(async () => { await natsClient.close(); }); // Install handlers lifecycle.install();

Sources: src/lifecycle/graceful-shutdown.ts:16-59, src/lifecycle/tests/graceful-shutdown.test.ts:47-56


Last modified on July 13, 2026
HTTP Server & Health ChecksModule Test Patterns
On this page
  • The GracefulShutdown Class
    • Key Components
    • Registration and Execution Flow
  • Signal Handling and Installation
    • Handled Events
  • Implementation Details
    • Re-entrancy Guard
    • Parallel Cleanup
    • Explicit Exit
  • Usage Example
TypeScript