Methods for starting, draining, and managing pool lifecycle with graceful shutdown capabilities, allowing for proper resource cleanup and controlled pool termination.
Manually starts the pool when autostart is disabled, initializing resource creation and eviction processes.
/**
* Starts the pool manually (when autostart is false)
* Begins resource creation to meet minimum pool size and starts eviction timer
*/
start(): void;Usage Examples:
// Create pool without autostart
const pool = genericPool.createPool(factory, {
max: 10,
min: 2,
autostart: false
});
// Start pool manually when ready
pool.start();
// Or start when needed
if (!pool._started) {
pool.start();
}
// Start pool and wait for readiness
pool.start();
await pool.ready();Waits for the pool to be fully started and initial resources created.
/**
* Waits for the pool to be fully started
* @returns Promise that resolves when pool startup is complete
*/
ready(): Promise<void>;Usage Examples:
// Wait for pool initialization
const pool = genericPool.createPool(factory, {
max: 10,
min: 5 // Will create 5 initial resources
});
await pool.ready(); // Wait for all initial resources to be created
console.log('Pool is ready with', pool.available, 'available resources');
// Application startup pattern
async function initializeApp() {
const dbPool = genericPool.createPool(dbFactory, { min: 3 });
const cachePool = genericPool.createPool(cacheFactory, { min: 2 });
await Promise.all([
dbPool.ready(),
cachePool.ready()
]);
console.log('All pools initialized');
startServer();
}Gracefully drains the pool, preventing new acquisitions while waiting for all borrowed resources to be returned.
/**
* Drains the pool, preventing new acquisitions and waiting for all resources to be returned
* @returns Promise that resolves when all borrowed resources are returned
*/
drain(): Promise<void>;Usage Examples:
// Graceful application shutdown
process.on('SIGTERM', async () => {
console.log('Shutting down gracefully...');
// Stop accepting new requests
server.close();
// Drain the pool - wait for active operations to complete
await pool.drain();
// Clean up remaining resources
await pool.clear();
process.exit(0);
});
// Manual drain and restart
async function restartPool() {
await pool.drain();
await pool.clear();
// Pool is now empty, can start fresh
const newResource = await pool.acquire();
// Pool automatically creates new resources as needed
}Destroys all available (idle) resources in the pool immediately.
/**
* Destroys all available resources in the pool
* @returns Promise that resolves when all available resources are destroyed
*/
clear(): Promise<void>;Usage Examples:
// Complete pool shutdown
async function shutdownPool() {
// First drain to wait for active operations
await pool.drain();
// Then clear all remaining resources
await pool.clear();
console.log('Pool completely shut down');
}
// Force clear during emergency shutdown
async function emergencyShutdown() {
try {
// Try to drain gracefully with timeout
await Promise.race([
pool.drain(),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Drain timeout')), 5000)
)
]);
} catch (error) {
console.log('Drain timed out, forcing clear');
}
await pool.clear();
}
// Clear and rebuild pool
async function refreshPool() {
const stats = {
sizeBefore: pool.size,
availableBefore: pool.available
};
await pool.clear();
console.log(`Cleared ${stats.availableBefore} resources`);
// Pool will create new resources as needed
const newResource = await pool.acquire();
await pool.release(newResource);
}Comprehensive lifecycle management patterns for different scenarios.
Usage Examples:
// Complete lifecycle management
class DatabaseService {
constructor() {
this.pool = genericPool.createPool(this.createFactory(), {
max: 20,
min: 2,
autostart: false
});
}
async start() {
this.pool.start();
await this.pool.ready();
console.log('Database service started');
}
async stop() {
console.log('Stopping database service...');
await this.pool.drain();
await this.pool.clear();
console.log('Database service stopped');
}
async restart() {
await this.stop();
await this.start();
}
createFactory() {
return {
create: async () => new DatabaseConnection(),
destroy: async (conn) => conn.close()
};
}
}
// Health check integration
async function healthCheck() {
return {
status: pool._started ? 'healthy' : 'not_started',
stats: {
size: pool.size,
available: pool.available,
borrowed: pool.borrowed,
pending: pool.pending
}
};
}
// Graceful process handling
async function setupGracefulShutdown(pools) {
const shutdown = async (signal) => {
console.log(`Received ${signal}, shutting down gracefully`);
// Drain all pools in parallel
await Promise.all(pools.map(pool => pool.drain()));
// Clear all pools
await Promise.all(pools.map(pool => pool.clear()));
console.log('All pools shut down successfully');
process.exit(0);
};
process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));
}Pool lifecycle integrates with the EventEmitter pattern for monitoring.
Usage Examples:
// Monitor pool lifecycle events
pool.on('factoryCreateError', (error) => {
console.error('Failed to create resource:', error);
// Could trigger pool restart or alerting
});
pool.on('factoryDestroyError', (error) => {
console.error('Failed to destroy resource:', error);
// Resource cleanup failed, might need manual intervention
});
// Custom lifecycle monitoring
class PoolMonitor {
constructor(pool) {
this.pool = pool;
this.startTime = Date.now();
this.errors = [];
pool.on('factoryCreateError', (error) => {
this.errors.push({ type: 'create', error, timestamp: Date.now() });
});
pool.on('factoryDestroyError', (error) => {
this.errors.push({ type: 'destroy', error, timestamp: Date.now() });
});
}
getStats() {
return {
uptime: Date.now() - this.startTime,
errors: this.errors.length,
recentErrors: this.errors.filter(e =>
Date.now() - e.timestamp < 300000 // Last 5 minutes
).length
};
}
}