API Lifecycle Management
Relevant source files
The following files were used as context for generating this wiki page:
The API Lifecycle Management system coordinates the startup and shutdown sequences for long-lived resources in the @thoth/api service. These resources include the HTTP server, database connections, metrics collectors, and background workers.
The system ensures that components initialize in a predictable order and clean up resources safely during termination. It handles process signals like SIGTERM and manages failures during the startup phase by rolling back initialized services.
Sources: apps/api/spec/lifecycle.md:1-10, apps/api/README.md:1-5
Core Components
The lifecycle architecture relies on a standard interface and a central manager to drive transitions.
Lifecycle Interface
Every long-lived resource implements a Lifecycle interface. This interface requires two asynchronous methods: start() to initialize the resource and stop() to release it.
Sources: apps/api/spec/lifecycle.md:10-12
LifecycleManager
The LifecycleManager maintains a registry of services and dictates the execution flow. It tracks registration order to ensure dependencies start before the services that rely on them.
Sources: apps/api/spec/lifecycle.md:12-13, apps/api/test/lifecycle/manager.test.ts:48-55
Operations and Rules
The management logic follows strict rules to maintain system stability.
| Rule ID | Action | Description |
|---|---|---|
| RULE-LIFECYCLE-001 | Start Order | Services start in the order they were registered. |
| RULE-LIFECYCLE-002 | Stop Order | Services stop in reverse registration order. |
| RULE-LIFECYCLE-003 | Failure Rollback | If a service fails to start, all previously started services stop in reverse order. |
| RULE-LIFECYCLE-004 | Timeout | Individual service stop() calls are wrapped in a timeout. |
| RULE-LIFECYCLE-005 | Error Resilience | If a service throws an error during shutdown, the manager logs it and continues to the next service. |
| RULE-LIFECYCLE-006 | Idempotency | Multiple calls to stop() trigger the shutdown sequence only once. |
Sources: apps/api/spec/lifecycle.md:16-25, apps/api/test/lifecycle/manager.test.ts:48-112
Startup Flow
When the application starts, the LifecycleManager iterates through its registry. If any service fails, it immediately initiates a partial shutdown of successful services to prevent resource leaks.
Shutdown and Signal Handling
The system captures OS signals and process-level errors to ensure a clean exit.
- Signals:
SIGTERMandSIGINTinvoke the manager's stop sequence and exit with code 0. - Exceptions: Unhandled rejections and uncaught exceptions log the error and exit with code 1.
- Repeats: The manager ignores duplicate signals received during an ongoing shutdown.
Integration with HTTP Infrastructure
The HttpServer is a primary participant in the lifecycle. It must be started before the API becomes reachable and stopped to drain active connections.
Health Probes
The lifecycle state affects the health check endpoints mounted via the HealthRouter:
/health/live: Returns200 OKonce the process is running./health/ready: Returns503 Degradedif queried before the lifecyclestart()sequence completes.
Sources: apps/api/test/infrastructure/http/server.integration.test.ts:80-95, apps/api/src/infrastructure/http/app-router.ts:50-55
Implementation Example
The following structure demonstrates how the LifecycleManager handles service registration and execution logic as seen in testing.
// Conceptual registration in the API main entry or DI container
manager.register(database);
manager.register(httpServer);
// Startup logic
await manager.start(); // Starts DB then HTTP
// Shutdown logic triggered by SIGTERM
await manager.stop(); // Stops HTTP then DB
Sources: apps/api/test/lifecycle/manager.test.ts:20-45, apps/api/test/infrastructure/http/server.integration.test.ts:40-45
Summary
API Lifecycle Management provides the @thoth/api service with a robust mechanism for resource coordination. By enforcing strict registration-based ordering and resilient error handling during transitions, it ensures the application remains stable during deployment shifts and unexpected process failures.