stock-bot/libs/core/shutdown/README.md

202 lines
4.4 KiB
Markdown

# @stock-bot/shutdown
Shutdown management library for Node.js applications in the Stock Bot platform.
## Features
-**Automatic Signal Handling** - SIGTERM, SIGINT, SIGUSR2 (Unix), uncaught exceptions
-**Platform Support** - Windows and Unix/Linux compatible
-**Multiple Callbacks** - Register multiple cleanup functions
-**Timeout Protection** - Configurable shutdown timeout
-**Error Handling** - Failed callbacks don't block shutdown
-**TypeScript Support** - Full type definitions
-**Zero Dependencies** - Lightweight and efficient
## Installation
```bash
bun add @stock-bot/shutdown
```
## Quick Start
```typescript
import { onShutdown, setShutdownTimeout } from '@stock-bot/shutdown';
// Configure shutdown timeout (optional, default: 30 seconds)
setShutdownTimeout(15000); // 15 seconds
// Register cleanup callbacks
onShutdown(async () => {
console.log('Closing database connections...');
await database.close();
});
onShutdown(async () => {
console.log('Stopping background jobs...');
await jobQueue.stop();
});
onShutdown(() => {
console.log('Final cleanup...');
// Synchronous cleanup
});
console.log('Application started. Press Ctrl+C to test graceful shutdown.');
```
## API Reference
### Convenience Functions
#### `onShutdown(callback)`
Register a cleanup callback.
```typescript
onShutdown(async () => {
await cleanup();
});
```
#### `setShutdownTimeout(timeout)`
Set shutdown timeout in milliseconds.
```typescript
setShutdownTimeout(30000); // 30 seconds
```
#### `initiateShutdown(signal?)`
Manually trigger shutdown.
```typescript
const result = await initiateShutdown('manual');
console.log(result.success); // true/false
```
#### `shutdownAndExit(signal?, exitCode?)`
Trigger shutdown and exit process.
```typescript
await shutdownAndExit('manual', 0);
```
### Advanced Usage
#### Manual Instance Management
```typescript
import { Shutdown } from '@stock-bot/shutdown';
const shutdown = new Shutdown({
timeout: 20000,
autoRegister: true
});
shutdown.onShutdown(async () => {
await cleanup();
});
// Manual shutdown
const result = await shutdown.shutdown('manual');
```
#### Configuration Options
```typescript
interface ShutdownOptions {
timeout?: number; // Timeout in ms (default: 30000)
autoRegister?: boolean; // Auto-register signals (default: true)
}
```
#### Shutdown Result
```typescript
interface ShutdownResult {
success: boolean;
callbacksExecuted: number;
callbacksFailed: number;
duration: number;
error?: string;
}
```
## Examples
### Express Server
```typescript
import express from 'express';
import { onShutdown, setShutdownTimeout } from '@stock-bot/shutdown';
const app = express();
const server = app.listen(3000);
setShutdownTimeout(10000);
onShutdown(async () => {
console.log('Closing HTTP server...');
await new Promise(resolve => server.close(resolve));
});
onShutdown(async () => {
console.log('Closing database...');
await database.close();
});
```
### Worker Process
```typescript
import { onShutdown } from '@stock-bot/shutdown';
let isRunning = true;
onShutdown(() => {
console.log('Stopping worker...');
isRunning = false;
});
// Worker loop
while (isRunning) {
await processJob();
await new Promise(resolve => setTimeout(resolve, 1000));
}
```
## Signal Handling
The library automatically handles these signals:
- **SIGTERM** - Termination request
- **SIGINT** - Interrupt (Ctrl+C)
- **SIGUSR2** - User-defined signal (Unix only)
- **uncaughtException** - Unhandled exceptions
- **unhandledRejection** - Unhandled promise rejections
On Windows, only SIGTERM and SIGINT are supported due to platform limitations.
## Best Practices
1. **Register callbacks early** in your application startup
2. **Keep callbacks simple** and focused on cleanup
3. **Use appropriate timeouts** based on your cleanup needs
4. **Handle errors gracefully** in callbacks
5. **Test shutdown behavior** in your CI/CD pipeline
## Testing
```typescript
import { resetShutdown, onShutdown } from '@stock-bot/shutdown';
beforeEach(() => {
resetShutdown(); // Clear previous state
});
test('should register shutdown callback', () => {
let cleaned = false;
onShutdown(() => { cleaned = true; });
// Test shutdown behavior
});
```