# @stock-bot/queue A reusable queue library with batch processing capabilities for the stock-bot project. ## Features - **Queue Management**: Built on BullMQ with Redis backing - **Batch Processing**: Efficient processing of large datasets - **Provider Registry**: Pluggable job handler system - **Cache Integration**: Uses @stock-bot/cache for payload storage - **TypeScript Support**: Full type safety and IntelliSense - **Configurable**: Flexible configuration for different environments ## Installation ```bash npm install @stock-bot/queue ``` ## Quick Start ### Basic Queue Setup ```typescript import { QueueManager, providerRegistry } from '@stock-bot/queue'; // Initialize queue manager const queueManager = new QueueManager({ queueName: 'my-service-queue', workers: 5, concurrency: 20, redis: { host: 'localhost', port: 6379, }, }); // Register providers providerRegistry.register('market-data', { 'fetch-price': async (payload) => { // Handle price fetching return { price: 100, symbol: payload.symbol }; }, 'update-data': async (payload) => { // Handle data updates return { success: true }; }, }); // Initialize await queueManager.initialize(); ``` ### Batch Processing ```typescript import { processItems, initializeBatchCache } from '@stock-bot/queue'; // Initialize cache first await initializeBatchCache(); // Process items in batches const result = await processItems( ['AAPL', 'GOOGL', 'MSFT'], (symbol, index) => ({ symbol, timestamp: Date.now() }), queueManager, { totalDelayMs: 60000, // 1 minute total useBatching: true, batchSize: 100, priority: 1, provider: 'market-data', operation: 'fetch-price', } ); console.log(result); // { // jobsCreated: 1, // mode: 'batch', // totalItems: 3, // batchesCreated: 1, // duration: 150 // } ``` ### Generic Processing ```typescript import { processItems } from '@stock-bot/queue'; const result = await processItems( ['AAPL', 'GOOGL', 'MSFT'], (symbol, index) => ({ symbol, index, timestamp: Date.now(), }), queueManager, { operation: 'live-data', provider: 'yahoo', totalDelayMs: 300000, // 5 minutes useBatching: false, priority: 1, } ); ``` ## API Reference ### QueueManager The main queue management class. #### Constructor ```typescript new QueueManager(config?: QueueConfig) ``` #### Methods - `initialize()`: Initialize the queue and workers - `registerProvider(name, config)`: Register a job provider - `add(name, data, options)`: Add a single job - `addBulk(jobs)`: Add multiple jobs in bulk - `getStats()`: Get queue statistics - `pause()`: Pause job processing - `resume()`: Resume job processing - `clean(grace, limit)`: Clean completed/failed jobs - `shutdown()`: Shutdown the queue manager ### Batch Processing Functions #### processItems() Process items either directly or in batches. ```typescript processItems( items: T[], processor: (item: T, index: number) => any, queue: QueueManager, options: ProcessOptions ): Promise ``` #### processBatchJob() Process a batch job (used internally by workers). ```typescript processBatchJob( jobData: BatchJobData, queue: QueueManager ): Promise ``` ### Provider Registry Manage job handlers for different providers. ```typescript // Register provider providerRegistry.register('provider-name', { 'operation-1': async (payload) => { /* handle */ }, 'operation-2': async (payload) => { /* handle */ }, }); // Check provider exists if (providerRegistry.hasProvider('provider-name')) { // Provider is registered } // Get handler const handler = providerRegistry.getHandler('provider-name', 'operation-1'); ``` ## Configuration ### QueueConfig ```typescript interface QueueConfig { workers?: number; // Number of worker processes concurrency?: number; // Jobs per worker redis?: { host?: string; port?: number; password?: string; db?: number; }; queueName?: string; // Name for the queue defaultJobOptions?: { removeOnComplete?: number; removeOnFail?: number; attempts?: number; backoff?: { type: string; delay: number; }; }; } ``` ### ProcessOptions ```typescript interface ProcessOptions { totalDelayMs: number; // Total time to spread jobs over batchSize?: number; // Items per batch (batch mode) priority?: number; // Job priority useBatching?: boolean; // Use batch vs direct mode retries?: number; // Number of retry attempts ttl?: number; // Cache TTL for batch payloads removeOnComplete?: number; // Keep N completed jobs removeOnFail?: number; // Keep N failed jobs provider?: string; // Provider name for job routing operation?: string; // Operation name for job routing } ``` ## Migration from Existing Queue If you're migrating from an existing queue implementation: 1. **Replace imports**: ```typescript // Before import { QueueService } from '../services/queue.service'; import { processItems } from '../utils/batch-helpers'; // After import { QueueManager, processItems } from '@stock-bot/queue'; ``` 2. **Update initialization**: ```typescript // Before const queueService = new QueueService(); await queueService.initialize(); // After const queueManager = new QueueManager(); await queueManager.initialize(); ``` 3. **Update provider registration**: ```typescript // Before providerRegistry.register('provider', config); // After queueManager.registerProvider('provider', config); ``` ## Examples See the `/examples` directory for complete implementation examples: - `basic-usage.ts` - Basic queue setup and job processing - `batch-processing.ts` - Advanced batch processing scenarios - `provider-setup.ts` - Provider registration patterns - `migration-example.ts` - Migration from existing queue service ## Best Practices 1. **Initialize cache before batch operations**: ```typescript await initializeBatchCache(); ``` 2. **Use appropriate batch sizes**: - Small items: 500-1000 per batch - Large items: 50-100 per batch 3. **Set reasonable delays**: - Spread jobs over time to avoid overwhelming services - Consider rate limits of external APIs 4. **Clean up periodically**: ```typescript await queueManager.clean(24 * 60 * 60 * 1000); // Clean jobs older than 24h ``` 5. **Monitor queue stats**: ```typescript const stats = await queueManager.getStats(); console.log('Queue status:', stats); ``` ## Environment Variables - `WORKER_COUNT`: Number of worker processes (default: 5) - `WORKER_CONCURRENCY`: Jobs per worker (default: 20) - `DRAGONFLY_HOST`: Redis/Dragonfly host (default: localhost) - `DRAGONFLY_PORT`: Redis/Dragonfly port (default: 6379) - `DRAGONFLY_PASSWORD`: Redis/Dragonfly password - `DRAGONFLY_DB`: Redis/Dragonfly database number (default: 0)