feat(server): Enqueue jobs in bulk (#5974)
* feat(server): Enqueue jobs in bulk The Job Repository now has a `queueAll` method, that enqueues messages in bulk (using BullMQ's [`addBulk`](https://docs.bullmq.io/guide/queues/adding-bulks)), improving performance when many jobs must be enqueued within the same operation. Primary change is in `src/domain/job/job.service.ts`, and other services have been refactored to use `queueAll` when useful. As a simple local benchmark, triggering a full thumbnail generation process over a library of ~1,200 assets and ~350 faces went from **~600ms** to **~250ms**. * fix: Review feedback
This commit is contained in:
committed by
GitHub
parent
7dd88c4114
commit
4a5b8c3770
@@ -342,7 +342,7 @@ describe(UserService.name, () => {
|
||||
userMock.update.mockResolvedValue({ ...userStub.admin, profileImagePath: file.path });
|
||||
|
||||
await sut.createProfileImage(authStub.admin, file);
|
||||
await expect(jobMock.queue.mock.calls).toEqual([[{ name: JobName.DELETE_FILES, data: { files } }]]);
|
||||
expect(jobMock.queue.mock.calls).toEqual([[{ name: JobName.DELETE_FILES, data: { files } }]]);
|
||||
});
|
||||
|
||||
it('should not delete the profile image if it has not been set', async () => {
|
||||
@@ -352,6 +352,7 @@ describe(UserService.name, () => {
|
||||
|
||||
await sut.createProfileImage(authStub.admin, file);
|
||||
expect(jobMock.queue).not.toHaveBeenCalled();
|
||||
expect(jobMock.queueAll).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -361,6 +362,7 @@ describe(UserService.name, () => {
|
||||
|
||||
await expect(sut.deleteProfileImage(authStub.admin)).rejects.toBeInstanceOf(BadRequestException);
|
||||
expect(jobMock.queue).not.toHaveBeenCalled();
|
||||
expect(jobMock.queueAll).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should delete the profile image if user has one', async () => {
|
||||
@@ -368,7 +370,7 @@ describe(UserService.name, () => {
|
||||
const files = [userStub.profilePath.profileImagePath];
|
||||
|
||||
await sut.deleteProfileImage(authStub.admin);
|
||||
await expect(jobMock.queue.mock.calls).toEqual([[{ name: JobName.DELETE_FILES, data: { files } }]]);
|
||||
expect(jobMock.queue.mock.calls).toEqual([[{ name: JobName.DELETE_FILES, data: { files } }]]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -456,6 +458,7 @@ describe(UserService.name, () => {
|
||||
|
||||
expect(userMock.getDeletedUsers).toHaveBeenCalled();
|
||||
expect(jobMock.queue).not.toHaveBeenCalled();
|
||||
expect(jobMock.queueAll).toHaveBeenCalledWith([]);
|
||||
});
|
||||
|
||||
it('should queue user ready for deletion', async () => {
|
||||
@@ -465,7 +468,7 @@ describe(UserService.name, () => {
|
||||
await sut.handleUserDeleteCheck();
|
||||
|
||||
expect(userMock.getDeletedUsers).toHaveBeenCalled();
|
||||
expect(jobMock.queue).toHaveBeenCalledWith({ name: JobName.USER_DELETION, data: { id: user.id } });
|
||||
expect(jobMock.queueAll).toHaveBeenCalledWith([{ name: JobName.USER_DELETION, data: { id: user.id } }]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -129,12 +129,11 @@ export class UserService {
|
||||
|
||||
async handleUserDeleteCheck() {
|
||||
const users = await this.userRepository.getDeletedUsers();
|
||||
for (const user of users) {
|
||||
if (this.isReadyForDeletion(user)) {
|
||||
await this.jobRepository.queue({ name: JobName.USER_DELETION, data: { id: user.id } });
|
||||
}
|
||||
}
|
||||
|
||||
await this.jobRepository.queueAll(
|
||||
users.flatMap((user) =>
|
||||
this.isReadyForDeletion(user) ? [{ name: JobName.USER_DELETION, data: { id: user.id } }] : [],
|
||||
),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user