queue work

This commit is contained in:
Boki 2025-06-19 08:22:00 -04:00
parent c05a7413dc
commit d3ef73ae00
9 changed files with 938 additions and 1086 deletions

View file

@ -1,5 +1,5 @@
import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
import { QueueManager, Queue, handlerRegistry, processItems, initializeBatchCache } from '../src';
import { QueueManager, Queue, handlerRegistry, processItems } from '../src';
// Suppress Redis connection errors in tests
process.on('unhandledRejection', (reason, promise) => {
@ -16,6 +16,7 @@ process.on('unhandledRejection', (reason, promise) => {
describe('Batch Processor', () => {
let queueManager: QueueManager;
let queue: Queue;
let queueName: string;
const redisConfig = {
host: 'localhost',
@ -44,21 +45,21 @@ describe('Batch Processor', () => {
});
// Use unique queue name per test to avoid conflicts
const uniqueQueueName = `batch-test-queue-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
queueName = `batch-test-queue-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
// Initialize queue manager with no workers to prevent immediate processing
queueManager = new QueueManager({
queueName: uniqueQueueName,
// Reset and initialize singleton QueueManager for tests
await QueueManager.reset();
queueManager = QueueManager.initialize({
redis: redisConfig,
workers: 0, // No workers in tests
concurrency: 5,
defaultQueueOptions: {
workers: 0, // No workers in tests
concurrency: 5,
},
});
await queueManager.initialize();
// Create Queue instance without worker to prevent immediate job processing
queue = new Queue(queueManager.getQueueName(), queueManager.getRedisConfig(), { startWorker: false });
await initializeBatchCache(queue);
// Get queue using the new getQueue() method (batch cache is now auto-initialized)
queue = queueManager.getQueue(queueName);
// Note: Batch cache is now automatically initialized when getting the queue
// Ensure completely clean state - wait for queue to be ready first
await queue.getBullQueue().waitUntilReady();
@ -89,12 +90,12 @@ describe('Batch Processor', () => {
} catch (error) {
// Ignore cleanup errors
}
await queue.shutdown();
await queue.close();
}
if (queueManager) {
await Promise.race([
queueManager.shutdown(),
QueueManager.reset(),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Shutdown timeout')), 3000)
)
@ -112,7 +113,7 @@ describe('Batch Processor', () => {
test('should process items directly without batching', async () => {
const items = ['item1', 'item2', 'item3', 'item4', 'item5'];
const result = await processItems(items, queue, {
const result = await processItems(items, queueName, {
totalDelayHours: 0.001, // 3.6 seconds total
useBatching: false,
handler: 'batch-test',
@ -158,7 +159,7 @@ describe('Batch Processor', () => {
{ id: 3, name: 'Product C', price: 300 },
];
const result = await processItems(items, queue, {
const result = await processItems(items, queueName, {
totalDelayHours: 0.001,
useBatching: false,
handler: 'batch-test',
@ -182,7 +183,7 @@ describe('Batch Processor', () => {
test('should process items in batches', async () => {
const items = Array.from({ length: 50 }, (_, i) => ({ id: i, value: `item-${i}` }));
const result = await processItems(items, queue, {
const result = await processItems(items, queueName, {
totalDelayHours: 0.001,
useBatching: true,
batchSize: 10,
@ -204,7 +205,7 @@ describe('Batch Processor', () => {
test('should handle different batch sizes', async () => {
const items = Array.from({ length: 23 }, (_, i) => i);
const result = await processItems(items, queue, {
const result = await processItems(items, queueName, {
totalDelayHours: 0.001,
useBatching: true,
batchSize: 7,
@ -222,7 +223,7 @@ describe('Batch Processor', () => {
{ type: 'B', data: 'test2' },
];
const result = await processItems(items, queue, {
const result = await processItems(items, queueName, {
totalDelayHours: 0.001,
useBatching: true,
batchSize: 2,
@ -245,7 +246,7 @@ describe('Batch Processor', () => {
describe('Empty and Edge Cases', () => {
test('should handle empty item list', async () => {
const result = await processItems([], queue, {
const result = await processItems([], queueName, {
totalDelayHours: 1,
handler: 'batch-test',
operation: 'process-item',
@ -257,7 +258,7 @@ describe('Batch Processor', () => {
});
test('should handle single item', async () => {
const result = await processItems(['single-item'], queue, {
const result = await processItems(['single-item'], queueName, {
totalDelayHours: 0.001,
handler: 'batch-test',
operation: 'process-item',
@ -270,7 +271,7 @@ describe('Batch Processor', () => {
test('should handle large batch with delays', async () => {
const items = Array.from({ length: 100 }, (_, i) => ({ index: i }));
const result = await processItems(items, queue, {
const result = await processItems(items, queueName, {
totalDelayHours: 0.01, // 36 seconds total
useBatching: true,
batchSize: 25,
@ -294,7 +295,7 @@ describe('Batch Processor', () => {
test('should respect custom job options', async () => {
const items = ['a', 'b', 'c'];
await processItems(items, queue, {
await processItems(items, queueName, {
totalDelayHours: 0,
handler: 'batch-test',
operation: 'process-item',
@ -339,7 +340,7 @@ describe('Batch Processor', () => {
},
});
await processItems(['test'], queue, {
await processItems(['test'], queueName, {
totalDelayHours: 0,
handler: 'custom-handler',
operation: 'custom-operation',