Ensure messages are sent in order, even with errors

This commit is contained in:
Evan Hahn 2021-09-07 15:39:14 -05:00 committed by GitHub
parent 634f4a8bb7
commit a3eed6191e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 348 additions and 244 deletions

View file

@ -8,6 +8,7 @@ import EventEmitter, { once } from 'events';
import { z } from 'zod';
import { noop, groupBy } from 'lodash';
import { v4 as uuid } from 'uuid';
import PQueue from 'p-queue';
import { JobError } from '../../jobs/JobError';
import { TestJobQueueStore } from './TestJobQueueStore';
import { missingCaseError } from '../../util/missingCaseError';
@ -67,6 +68,98 @@ describe('JobQueue', () => {
assert.isEmpty(store.storedJobs);
});
it('by default, kicks off multiple jobs in parallel', async () => {
let activeJobCount = 0;
const eventBus = new EventEmitter();
const updateActiveJobCount = (incrementBy: number): void => {
activeJobCount += incrementBy;
eventBus.emit('updated');
};
class Queue extends JobQueue<number> {
parseData(data: unknown): number {
return z.number().parse(data);
}
async run(): Promise<void> {
try {
updateActiveJobCount(1);
await new Promise<void>(resolve => {
eventBus.on('updated', () => {
if (activeJobCount === 4) {
eventBus.emit('got to 4');
resolve();
}
});
});
} finally {
updateActiveJobCount(-1);
}
}
}
const store = new TestJobQueueStore();
const queue = new Queue({
store,
queueType: 'test queue',
maxAttempts: 100,
});
queue.streamJobs();
queue.add(1);
queue.add(2);
queue.add(3);
queue.add(4);
await once(eventBus, 'got to 4');
});
it('can override the in-memory queue', async () => {
let jobsAdded = 0;
const testQueue = new PQueue();
testQueue.on('add', () => {
jobsAdded += 1;
});
class Queue extends JobQueue<number> {
parseData(data: unknown): number {
return z.number().parse(data);
}
protected getInMemoryQueue(parsedJob: ParsedJob<number>): PQueue {
assert(
new Set([1, 2, 3, 4]).has(parsedJob.data),
'Bad data passed to `getInMemoryQueue`'
);
return testQueue;
}
run(): Promise<void> {
return Promise.resolve();
}
}
const store = new TestJobQueueStore();
const queue = new Queue({
store,
queueType: 'test queue',
maxAttempts: 100,
});
queue.streamJobs();
const jobs = await Promise.all([
queue.add(1),
queue.add(2),
queue.add(3),
queue.add(4),
]);
await Promise.all(jobs.map(job => job.completion));
assert.strictEqual(jobsAdded, 4);
});
it('writes jobs to the database correctly', async () => {
const store = new TestJobQueueStore();