202 lines
4.4 KiB
Markdown
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
|
|
});
|
|
```
|