diff --git a/server/src/enum.ts b/server/src/enum.ts index 1d8b8645d1..587a76126f 100644 --- a/server/src/enum.ts +++ b/server/src/enum.ts @@ -441,94 +441,75 @@ export enum QueueName { } export enum JobName { - //backups - BackupDatabase = 'database-backup', + AssetDelete = 'AssetDelete', + AssetDeleteCheck = 'AssetDeleteCheck', + AssetDetectFacesQueueAll = 'AssetDetectFacesQueueAll', + AssetDetectFaces = 'AssetDetectFaces', + AssetDetectDuplicatesQueueAll = 'AssetDetectDuplicatesQueueAll', + AssetDetectDuplicates = 'AssetDetectDuplicates', + AssetEncodeVideoQueueAll = 'AssetEncodeVideoQueueAll', + AssetEncodeVideo = 'AssetEncodeVideo', + AssetEmptyTrash = 'AssetEmptyTrash', + AssetExtractMetadataQueueAll = 'AssetExtractMetadataQueueAll', + AssetExtractMetadata = 'AssetExtractMetadata', + AssetFileMigration = 'AssetFileMigration', + AssetGenerateThumbnailsQueueAll = 'AssetGenerateThumbnailsQueueAll', + AssetGenerateThumbnails = 'AssetGenerateThumbnails', - // conversion - QueueVideoConversion = 'queue-video-conversion', - VideoConversation = 'video-conversion', + AuditLogCleanup = 'AuditLogCleanup', - // thumbnails - QueueGenerateThumbnails = 'queue-generate-thumbnails', - GenerateThumbnails = 'generate-thumbnails', - GeneratePersonThumbnail = 'generate-person-thumbnail', + DatabaseBackup = 'DatabaseBackup', - // metadata - QueueMetadataExtraction = 'queue-metadata-extraction', - MetadataExtraction = 'metadata-extraction', + FacialRecognitionQueueAll = 'FacialRecognitionQueueAll', + FacialRecognition = 'FacialRecognition', - // user - UserDeletion = 'user-deletion', - UserDeleteCheck = 'user-delete-check', - userSyncUsage = 'user-sync-usage', + FileDelete = 'FileDelete', + FileMigrationQueueAll = 'FileMigrationQueueAll', - // asset - AssetDeletion = 'asset-deletion', - AssetDeletionCheck = 'asset-deletion-check', + LibraryDeleteCheck = 'LibraryDeleteCheck', + LibraryDelete = 'LibraryDelete', + LibraryRemoveAsset = 'LibraryRemoveAsset', + LibrarySyncAssetsQueueAll = 'LibraryScanAssetsQueueAll', + LibrarySyncAssets = 'LibrarySyncAssets', + LibrarySyncFilesQueueAll = 'LibrarySyncFilesQueueAll', + LibrarySyncFiles = 'LibrarySyncFiles', + LibraryScanQueueAll = 'LibraryScanQueueAll', - // storage template - StorageTemplateMigration = 'storage-template-migration', - StorageTemplateMigrationSingle = 'storage-template-migration-single', + MemoryCleanup = 'MemoryCleanup', + MemoryGenerate = 'MemoryGenerate', - // tags - TagCleanup = 'tag-cleanup', + NotificationsCleanup = 'NotificationsCleanup', - // migration - QueueMigration = 'queue-migration', - MigrateAsset = 'migrate-asset', - MigratePerson = 'migrate-person', + NotifyUserSignup = 'NotifyUserSignup', + NotifyAlbumInvite = 'NotifyAlbumInvite', + NotifyAlbumUpdate = 'NotifyAlbumUpdate', - // facial recognition - PersonCleanup = 'person-cleanup', - QueueFaceDetection = 'queue-face-detection', - FaceDetection = 'face-detection', - QueueFacialRecognition = 'queue-facial-recognition', - FacialRecognition = 'facial-recognition', + UserDelete = 'UserDelete', + UserDeleteCheck = 'UserDeleteCheck', + UserSyncUsage = 'UserSyncUsage', - // library management - LibraryQueueSyncFiles = 'library-queue-sync-files', - LibraryQueueSyncAssets = 'library-queue-sync-assets', - LibrarySyncFiles = 'library-sync-files', - LibrarySyncAssets = 'library-sync-assets', - LibraryAssetRemoval = 'handle-library-file-deletion', - LibraryDelete = 'library-delete', - LibraryQueueScanAll = 'library-queue-scan-all', - LibraryQueueCleanup = 'library-queue-cleanup', + PersonCleanup = 'PersonCleanup', + PersonFileMigration = 'PersonFileMigration', + PersonGenerateThumbnail = 'PersonGenerateThumbnail', - // cleanup - DeleteFiles = 'delete-files', - CleanOldAuditLogs = 'clean-old-audit-logs', - CleanOldSessionTokens = 'clean-old-session-tokens', + SessionCleanup = 'SessionCleanup', - // memories - MemoriesCleanup = 'memories-cleanup', - MemoriesCreate = 'memories-create', + SendMail = 'SendMail', - // smart search - QueueSmartSearch = 'queue-smart-search', - SmartSearch = 'smart-search', + SidecarQueueAll = 'SidecarQueueAll', + SidecarDiscovery = 'SidecarDiscovery', + SidecarSync = 'SidecarSync', + SidecarWrite = 'SidecarWrite', - QueueTrashEmpty = 'queue-trash-empty', + SmartSearchQueueAll = 'SmartSearchQueueAll', + SmartSearch = 'SmartSearch', - // duplicate detection - QueueDuplicateDetection = 'queue-duplicate-detection', - DuplicateDetection = 'duplicate-detection', + StorageTemplateMigration = 'StorageTemplateMigration', + StorageTemplateMigrationSingle = 'StorageTemplateMigrationSingle', - // XMP sidecars - QueueSidecar = 'queue-sidecar', - SidecarDiscovery = 'sidecar-discovery', - SidecarSync = 'sidecar-sync', - SidecarWrite = 'sidecar-write', + TagCleanup = 'TagCleanup', - // Notification - NotifySignup = 'notify-signup', - NotifyAlbumInvite = 'notify-album-invite', - NotifyAlbumUpdate = 'notify-album-update', - NotificationsCleanup = 'notifications-cleanup', - SendMail = 'notification-send-email', - - // Version check - VersionCheck = 'version-check', + VersionCheck = 'VersionCheck', } export enum JobCommand { diff --git a/server/src/repositories/job.repository.ts b/server/src/repositories/job.repository.ts index 3550529bfc..5acd8d5746 100644 --- a/server/src/repositories/job.repository.ts +++ b/server/src/repositories/job.repository.ts @@ -214,11 +214,11 @@ export class JobRepository { case JobName.StorageTemplateMigrationSingle: { return { jobId: item.data.id }; } - case JobName.GeneratePersonThumbnail: { + case JobName.PersonGenerateThumbnail: { return { priority: 1 }; } - case JobName.QueueFacialRecognition: { - return { jobId: JobName.QueueFacialRecognition }; + case JobName.FacialRecognitionQueueAll: { + return { jobId: JobName.FacialRecognitionQueueAll }; } default: { return null; diff --git a/server/src/services/asset-media.service.spec.ts b/server/src/services/asset-media.service.spec.ts index c881ebb497..dccb79c585 100644 --- a/server/src/services/asset-media.service.spec.ts +++ b/server/src/services/asset-media.service.spec.ts @@ -384,7 +384,7 @@ describe(AssetMediaService.name, () => { }); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.DeleteFiles, + name: JobName.FileDelete, data: { files: ['fake_path/asset_1.jpeg', undefined] }, }); expect(mocks.user.updateUsage).not.toHaveBeenCalled(); @@ -409,7 +409,7 @@ describe(AssetMediaService.name, () => { ); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.DeleteFiles, + name: JobName.FileDelete, data: { files: ['fake_path/asset_1.jpeg', undefined] }, }); expect(mocks.user.updateUsage).not.toHaveBeenCalled(); @@ -815,7 +815,7 @@ describe(AssetMediaService.name, () => { expect(mocks.asset.create).not.toHaveBeenCalled(); expect(mocks.asset.updateAll).not.toHaveBeenCalled(); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.DeleteFiles, + name: JobName.FileDelete, data: { files: [updatedFile.originalPath, undefined] }, }); expect(mocks.user.updateUsage).not.toHaveBeenCalled(); @@ -912,7 +912,7 @@ describe(AssetMediaService.name, () => { await sut.onUploadError(request, file); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.DeleteFiles, + name: JobName.FileDelete, data: { files: ['upload/upload/user-id/ra/nd/random-uuid.jpg'] }, }); }); diff --git a/server/src/services/asset-media.service.ts b/server/src/services/asset-media.service.ts index 127fdbe8eb..080774d038 100644 --- a/server/src/services/asset-media.service.ts +++ b/server/src/services/asset-media.service.ts @@ -121,7 +121,7 @@ export class AssetMediaService extends BaseService { const uploadFolder = this.getUploadFolder(asRequest(request, file)); const uploadPath = `${uploadFolder}/${uploadFilename}`; - await this.jobRepository.queue({ name: JobName.DeleteFiles, data: { files: [uploadPath] } }); + await this.jobRepository.queue({ name: JobName.FileDelete, data: { files: [uploadPath] } }); } async uploadAsset( @@ -312,7 +312,7 @@ export class AssetMediaService extends BaseService { ): Promise { // clean up files await this.jobRepository.queue({ - name: JobName.DeleteFiles, + name: JobName.FileDelete, data: { files: [file.originalPath, sidecarFile?.originalPath] }, }); @@ -365,7 +365,7 @@ export class AssetMediaService extends BaseService { await this.storageRepository.utimes(file.originalPath, new Date(), new Date(dto.fileModifiedAt)); await this.assetRepository.upsertExif({ assetId, fileSizeInByte: file.size }); await this.jobRepository.queue({ - name: JobName.MetadataExtraction, + name: JobName.AssetExtractMetadata, data: { id: assetId, source: 'upload' }, }); } @@ -394,7 +394,7 @@ export class AssetMediaService extends BaseService { const { size } = await this.storageRepository.stat(created.originalPath); await this.assetRepository.upsertExif({ assetId: created.id, fileSizeInByte: size }); - await this.jobRepository.queue({ name: JobName.MetadataExtraction, data: { id: created.id, source: 'copy' } }); + await this.jobRepository.queue({ name: JobName.AssetExtractMetadata, data: { id: created.id, source: 'copy' } }); return created; } @@ -427,7 +427,7 @@ export class AssetMediaService extends BaseService { } await this.storageRepository.utimes(file.originalPath, new Date(), new Date(dto.fileModifiedAt)); await this.assetRepository.upsertExif({ assetId: asset.id, fileSizeInByte: file.size }); - await this.jobRepository.queue({ name: JobName.MetadataExtraction, data: { id: asset.id, source: 'upload' } }); + await this.jobRepository.queue({ name: JobName.AssetExtractMetadata, data: { id: asset.id, source: 'upload' } }); return asset; } diff --git a/server/src/services/asset.service.spec.ts b/server/src/services/asset.service.spec.ts index 606c93eab8..6461735976 100755 --- a/server/src/services/asset.service.spec.ts +++ b/server/src/services/asset.service.spec.ts @@ -522,7 +522,7 @@ describe(AssetService.name, () => { expect(mocks.assetJob.streamForDeletedJob).toHaveBeenCalledWith(new Date()); expect(mocks.job.queueAll).toHaveBeenCalledWith([ - { name: JobName.AssetDeletion, data: { id: asset.id, deleteOnDisk: true } }, + { name: JobName.AssetDelete, data: { id: asset.id, deleteOnDisk: true } }, ]); }); @@ -536,7 +536,7 @@ describe(AssetService.name, () => { expect(mocks.assetJob.streamForDeletedJob).toHaveBeenCalledWith(DateTime.now().minus({ days: 7 }).toJSDate()); expect(mocks.job.queueAll).toHaveBeenCalledWith([ - { name: JobName.AssetDeletion, data: { id: asset.id, deleteOnDisk: true } }, + { name: JobName.AssetDelete, data: { id: asset.id, deleteOnDisk: true } }, ]); }); }); @@ -552,7 +552,7 @@ describe(AssetService.name, () => { expect(mocks.job.queue.mock.calls).toEqual([ [ { - name: JobName.DeleteFiles, + name: JobName.FileDelete, data: { files: [ '/uploads/user-id/webp/path.ext', @@ -606,7 +606,7 @@ describe(AssetService.name, () => { expect(mocks.job.queue.mock.calls).toEqual([ [ { - name: JobName.AssetDeletion, + name: JobName.AssetDelete, data: { id: assetStub.livePhotoMotionAsset.id, deleteOnDisk: true, @@ -615,7 +615,7 @@ describe(AssetService.name, () => { ], [ { - name: JobName.DeleteFiles, + name: JobName.FileDelete, data: { files: [ '/uploads/user-id/webp/path.ext', @@ -643,7 +643,7 @@ describe(AssetService.name, () => { expect(mocks.job.queue.mock.calls).toEqual([ [ { - name: JobName.DeleteFiles, + name: JobName.FileDelete, data: { files: [ '/uploads/user-id/webp/path.ext', @@ -679,7 +679,7 @@ describe(AssetService.name, () => { await sut.run(authStub.admin, { assetIds: ['asset-1'], name: AssetJobName.REFRESH_FACES }); - expect(mocks.job.queueAll).toHaveBeenCalledWith([{ name: JobName.FaceDetection, data: { id: 'asset-1' } }]); + expect(mocks.job.queueAll).toHaveBeenCalledWith([{ name: JobName.AssetDetectFaces, data: { id: 'asset-1' } }]); }); it('should run the refresh metadata job', async () => { @@ -687,7 +687,9 @@ describe(AssetService.name, () => { await sut.run(authStub.admin, { assetIds: ['asset-1'], name: AssetJobName.REFRESH_METADATA }); - expect(mocks.job.queueAll).toHaveBeenCalledWith([{ name: JobName.MetadataExtraction, data: { id: 'asset-1' } }]); + expect(mocks.job.queueAll).toHaveBeenCalledWith([ + { name: JobName.AssetExtractMetadata, data: { id: 'asset-1' } }, + ]); }); it('should run the refresh thumbnails job', async () => { @@ -695,7 +697,9 @@ describe(AssetService.name, () => { await sut.run(authStub.admin, { assetIds: ['asset-1'], name: AssetJobName.REGENERATE_THUMBNAIL }); - expect(mocks.job.queueAll).toHaveBeenCalledWith([{ name: JobName.GenerateThumbnails, data: { id: 'asset-1' } }]); + expect(mocks.job.queueAll).toHaveBeenCalledWith([ + { name: JobName.AssetGenerateThumbnails, data: { id: 'asset-1' } }, + ]); }); it('should run the transcode video', async () => { @@ -703,7 +707,7 @@ describe(AssetService.name, () => { await sut.run(authStub.admin, { assetIds: ['asset-1'], name: AssetJobName.TRANSCODE_VIDEO }); - expect(mocks.job.queueAll).toHaveBeenCalledWith([{ name: JobName.VideoConversation, data: { id: 'asset-1' } }]); + expect(mocks.job.queueAll).toHaveBeenCalledWith([{ name: JobName.AssetEncodeVideo, data: { id: 'asset-1' } }]); }); }); diff --git a/server/src/services/asset.service.ts b/server/src/services/asset.service.ts index d9b0527d5b..864a9cc512 100644 --- a/server/src/services/asset.service.ts +++ b/server/src/services/asset.service.ts @@ -145,7 +145,7 @@ export class AssetService extends BaseService { } } - @OnJob({ name: JobName.AssetDeletionCheck, queue: QueueName.BackgroundTask }) + @OnJob({ name: JobName.AssetDeleteCheck, queue: QueueName.BackgroundTask }) async handleAssetDeletionCheck(): Promise { const config = await this.getConfig({ withCache: false }); const trashedDays = config.trash.enabled ? config.trash.days : 0; @@ -158,7 +158,7 @@ export class AssetService extends BaseService { if (chunk.length > 0) { await this.jobRepository.queueAll( chunk.map(({ id, isOffline }) => ({ - name: JobName.AssetDeletion, + name: JobName.AssetDelete, data: { id, deleteOnDisk: !isOffline }, })), ); @@ -179,8 +179,8 @@ export class AssetService extends BaseService { return JobStatus.Success; } - @OnJob({ name: JobName.AssetDeletion, queue: QueueName.BackgroundTask }) - async handleAssetDeletion(job: JobOf): Promise { + @OnJob({ name: JobName.AssetDelete, queue: QueueName.BackgroundTask }) + async handleAssetDeletion(job: JobOf): Promise { const { id, deleteOnDisk } = job; const asset = await this.assetJobRepository.getForAssetDeletion(id); @@ -215,7 +215,7 @@ export class AssetService extends BaseService { const count = await this.assetRepository.getLivePhotoCount(asset.livePhotoVideoId); if (count === 0) { await this.jobRepository.queue({ - name: JobName.AssetDeletion, + name: JobName.AssetDelete, data: { id: asset.livePhotoVideoId, deleteOnDisk }, }); } @@ -228,7 +228,7 @@ export class AssetService extends BaseService { files.push(asset.sidecarPath, asset.originalPath); } - await this.jobRepository.queue({ name: JobName.DeleteFiles, data: { files } }); + await this.jobRepository.queue({ name: JobName.FileDelete, data: { files } }); return JobStatus.Success; } @@ -255,22 +255,22 @@ export class AssetService extends BaseService { for (const id of dto.assetIds) { switch (dto.name) { case AssetJobName.REFRESH_FACES: { - jobs.push({ name: JobName.FaceDetection, data: { id } }); + jobs.push({ name: JobName.AssetDetectFaces, data: { id } }); break; } case AssetJobName.REFRESH_METADATA: { - jobs.push({ name: JobName.MetadataExtraction, data: { id } }); + jobs.push({ name: JobName.AssetExtractMetadata, data: { id } }); break; } case AssetJobName.REGENERATE_THUMBNAIL: { - jobs.push({ name: JobName.GenerateThumbnails, data: { id } }); + jobs.push({ name: JobName.AssetGenerateThumbnails, data: { id } }); break; } case AssetJobName.TRANSCODE_VIDEO: { - jobs.push({ name: JobName.VideoConversation, data: { id } }); + jobs.push({ name: JobName.AssetEncodeVideo, data: { id } }); break; } } diff --git a/server/src/services/audit.service.ts b/server/src/services/audit.service.ts index eaa48de1f4..498d99b82c 100644 --- a/server/src/services/audit.service.ts +++ b/server/src/services/audit.service.ts @@ -7,7 +7,7 @@ import { BaseService } from 'src/services/base.service'; @Injectable() export class AuditService extends BaseService { - @OnJob({ name: JobName.CleanOldAuditLogs, queue: QueueName.BackgroundTask }) + @OnJob({ name: JobName.AuditLogCleanup, queue: QueueName.BackgroundTask }) async handleCleanup(): Promise { await this.auditRepository.removeBefore(DateTime.now().minus(AUDIT_LOG_MAX_DURATION).toJSDate()); return JobStatus.Success; diff --git a/server/src/services/auth.service.ts b/server/src/services/auth.service.ts index 00b7c1e9aa..a5b0de25cd 100644 --- a/server/src/services/auth.service.ts +++ b/server/src/services/auth.service.ts @@ -330,7 +330,7 @@ export class AuthService extends BaseService { await this.userRepository.update(user.id, { profileImagePath, profileChangedAt: new Date() }); if (oldPath) { - await this.jobRepository.queue({ name: JobName.DeleteFiles, data: { files: [oldPath] } }); + await this.jobRepository.queue({ name: JobName.FileDelete, data: { files: [oldPath] } }); } } catch (error: Error | any) { this.logger.warn(`Unable to sync oauth profile picture: ${error}`, error?.stack); diff --git a/server/src/services/backup.service.ts b/server/src/services/backup.service.ts index a5882b4f80..9daa2c3aea 100644 --- a/server/src/services/backup.service.ts +++ b/server/src/services/backup.service.ts @@ -26,7 +26,7 @@ export class BackupService extends BaseService { this.cronRepository.create({ name: 'backupDatabase', expression: database.cronExpression, - onTick: () => handlePromiseError(this.jobRepository.queue({ name: JobName.BackupDatabase }), this.logger), + onTick: () => handlePromiseError(this.jobRepository.queue({ name: JobName.DatabaseBackup }), this.logger), start: database.enabled, }); } @@ -68,7 +68,7 @@ export class BackupService extends BaseService { this.logger.debug(`Database Backup Cleanup Finished, deleted ${toDelete.length} backups`); } - @OnJob({ name: JobName.BackupDatabase, queue: QueueName.BackupDatabase }) + @OnJob({ name: JobName.DatabaseBackup, queue: QueueName.BackupDatabase }) async handleBackupDatabase(): Promise { this.logger.debug(`Database Backup Started`); const { database } = this.configRepository.getEnv(); diff --git a/server/src/services/duplicate.service.spec.ts b/server/src/services/duplicate.service.spec.ts index 0a2243e322..e5ac9f82ba 100644 --- a/server/src/services/duplicate.service.spec.ts +++ b/server/src/services/duplicate.service.spec.ts @@ -108,7 +108,7 @@ describe(SearchService.name, () => { expect(mocks.assetJob.streamForSearchDuplicates).toHaveBeenCalledWith(undefined); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.DuplicateDetection, + name: JobName.AssetDetectDuplicates, data: { id: assetStub.image.id }, }, ]); @@ -122,7 +122,7 @@ describe(SearchService.name, () => { expect(mocks.assetJob.streamForSearchDuplicates).toHaveBeenCalledWith(true); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.DuplicateDetection, + name: JobName.AssetDetectDuplicates, data: { id: assetStub.image.id }, }, ]); diff --git a/server/src/services/duplicate.service.ts b/server/src/services/duplicate.service.ts index 1699cf73f6..618754ff74 100644 --- a/server/src/services/duplicate.service.ts +++ b/server/src/services/duplicate.service.ts @@ -29,8 +29,8 @@ export class DuplicateService extends BaseService { await this.duplicateRepository.deleteAll(auth.user.id, dto.ids); } - @OnJob({ name: JobName.QueueDuplicateDetection, queue: QueueName.DuplicateDetection }) - async handleQueueSearchDuplicates({ force }: JobOf): Promise { + @OnJob({ name: JobName.AssetDetectDuplicatesQueueAll, queue: QueueName.DuplicateDetection }) + async handleQueueSearchDuplicates({ force }: JobOf): Promise { const { machineLearning } = await this.getConfig({ withCache: false }); if (!isDuplicateDetectionEnabled(machineLearning)) { return JobStatus.Skipped; @@ -44,7 +44,7 @@ export class DuplicateService extends BaseService { const assets = this.assetJobRepository.streamForSearchDuplicates(force); for await (const asset of assets) { - jobs.push({ name: JobName.DuplicateDetection, data: { id: asset.id } }); + jobs.push({ name: JobName.AssetDetectDuplicates, data: { id: asset.id } }); if (jobs.length >= JOBS_ASSET_PAGINATION_SIZE) { await queueAll(); } @@ -55,8 +55,8 @@ export class DuplicateService extends BaseService { return JobStatus.Success; } - @OnJob({ name: JobName.DuplicateDetection, queue: QueueName.DuplicateDetection }) - async handleSearchDuplicates({ id }: JobOf): Promise { + @OnJob({ name: JobName.AssetDetectDuplicates, queue: QueueName.DuplicateDetection }) + async handleSearchDuplicates({ id }: JobOf): Promise { const { machineLearning } = await this.getConfig({ withCache: true }); if (!isDuplicateDetectionEnabled(machineLearning)) { return JobStatus.Skipped; diff --git a/server/src/services/job.service.spec.ts b/server/src/services/job.service.spec.ts index 497d81b4ca..a57db736af 100644 --- a/server/src/services/job.service.spec.ts +++ b/server/src/services/job.service.spec.ts @@ -37,16 +37,16 @@ describe(JobService.name, () => { await sut.handleNightlyJobs(); expect(mocks.job.queueAll).toHaveBeenCalledWith([ - { name: JobName.AssetDeletionCheck }, + { name: JobName.AssetDeleteCheck }, { name: JobName.UserDeleteCheck }, { name: JobName.PersonCleanup }, - { name: JobName.MemoriesCleanup }, - { name: JobName.CleanOldSessionTokens }, - { name: JobName.CleanOldAuditLogs }, - { name: JobName.MemoriesCreate }, - { name: JobName.userSyncUsage }, - { name: JobName.QueueGenerateThumbnails, data: { force: false } }, - { name: JobName.QueueFacialRecognition, data: { force: false, nightly: true } }, + { name: JobName.MemoryCleanup }, + { name: JobName.SessionCleanup }, + { name: JobName.AuditLogCleanup }, + { name: JobName.MemoryGenerate }, + { name: JobName.UserSyncUsage }, + { name: JobName.AssetGenerateThumbnailsQueueAll, data: { force: false } }, + { name: JobName.FacialRecognitionQueueAll, data: { force: false, nightly: true } }, ]); }); }); @@ -136,7 +136,7 @@ describe(JobService.name, () => { await sut.handleCommand(QueueName.VideoConversion, { command: JobCommand.Start, force: false }); - expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.QueueVideoConversion, data: { force: false } }); + expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.AssetEncodeVideoQueueAll, data: { force: false } }); }); it('should handle a start storage template migration command', async () => { @@ -152,7 +152,7 @@ describe(JobService.name, () => { await sut.handleCommand(QueueName.SmartSearch, { command: JobCommand.Start, force: false }); - expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.QueueSmartSearch, data: { force: false } }); + expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.SmartSearchQueueAll, data: { force: false } }); }); it('should handle a start metadata extraction command', async () => { @@ -160,7 +160,10 @@ describe(JobService.name, () => { await sut.handleCommand(QueueName.MetadataExtraction, { command: JobCommand.Start, force: false }); - expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.QueueMetadataExtraction, data: { force: false } }); + expect(mocks.job.queue).toHaveBeenCalledWith({ + name: JobName.AssetExtractMetadataQueueAll, + data: { force: false }, + }); }); it('should handle a start sidecar command', async () => { @@ -168,7 +171,7 @@ describe(JobService.name, () => { await sut.handleCommand(QueueName.Sidecar, { command: JobCommand.Start, force: false }); - expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.QueueSidecar, data: { force: false } }); + expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.SidecarQueueAll, data: { force: false } }); }); it('should handle a start thumbnail generation command', async () => { @@ -176,7 +179,10 @@ describe(JobService.name, () => { await sut.handleCommand(QueueName.ThumbnailGeneration, { command: JobCommand.Start, force: false }); - expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.QueueGenerateThumbnails, data: { force: false } }); + expect(mocks.job.queue).toHaveBeenCalledWith({ + name: JobName.AssetGenerateThumbnailsQueueAll, + data: { force: false }, + }); }); it('should handle a start face detection command', async () => { @@ -184,7 +190,7 @@ describe(JobService.name, () => { await sut.handleCommand(QueueName.FaceDetection, { command: JobCommand.Start, force: false }); - expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.QueueFaceDetection, data: { force: false } }); + expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.AssetDetectFacesQueueAll, data: { force: false } }); }); it('should handle a start facial recognition command', async () => { @@ -192,7 +198,7 @@ describe(JobService.name, () => { await sut.handleCommand(QueueName.FacialRecognition, { command: JobCommand.Start, force: false }); - expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.QueueFacialRecognition, data: { force: false } }); + expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.FacialRecognitionQueueAll, data: { force: false } }); }); it('should handle a start backup database command', async () => { @@ -200,7 +206,7 @@ describe(JobService.name, () => { await sut.handleCommand(QueueName.BackupDatabase, { command: JobCommand.Start, force: false }); - expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.BackupDatabase, data: { force: false } }); + expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.DatabaseBackup, data: { force: false } }); }); it('should throw a bad request when an invalid queue is used', async () => { @@ -220,55 +226,55 @@ describe(JobService.name, () => { mocks.job.run.mockResolvedValue(JobStatus.Success); await sut.onJobStart(QueueName.BackgroundTask, { - name: JobName.DeleteFiles, + name: JobName.FileDelete, data: { files: ['path/to/file'] }, }); expect(mocks.telemetry.jobs.addToGauge).toHaveBeenCalledWith('immich.queues.background_task.active', 1); expect(mocks.telemetry.jobs.addToGauge).toHaveBeenCalledWith('immich.queues.background_task.active', -1); - expect(mocks.telemetry.jobs.addToCounter).toHaveBeenCalledWith('immich.jobs.delete_files.success', 1); + expect(mocks.telemetry.jobs.addToCounter).toHaveBeenCalledWith('immich.jobs.file_delete.success', 1); expect(mocks.logger.error).not.toHaveBeenCalled(); }); const tests: Array<{ item: JobItem; jobs: JobName[]; stub?: any }> = [ { item: { name: JobName.SidecarSync, data: { id: 'asset-1' } }, - jobs: [JobName.MetadataExtraction], + jobs: [JobName.AssetExtractMetadata], }, { item: { name: JobName.SidecarDiscovery, data: { id: 'asset-1' } }, - jobs: [JobName.MetadataExtraction], + jobs: [JobName.AssetExtractMetadata], }, { item: { name: JobName.StorageTemplateMigrationSingle, data: { id: 'asset-1', source: 'upload' } }, - jobs: [JobName.GenerateThumbnails], + jobs: [JobName.AssetGenerateThumbnails], }, { item: { name: JobName.StorageTemplateMigrationSingle, data: { id: 'asset-1' } }, jobs: [], }, { - item: { name: JobName.GeneratePersonThumbnail, data: { id: 'asset-1' } }, + item: { name: JobName.PersonGenerateThumbnail, data: { id: 'asset-1' } }, jobs: [], }, { - item: { name: JobName.GenerateThumbnails, data: { id: 'asset-1' } }, + item: { name: JobName.AssetGenerateThumbnails, data: { id: 'asset-1' } }, jobs: [], stub: [assetStub.image], }, { - item: { name: JobName.GenerateThumbnails, data: { id: 'asset-1' } }, + item: { name: JobName.AssetGenerateThumbnails, data: { id: 'asset-1' } }, jobs: [], stub: [assetStub.video], }, { - item: { name: JobName.GenerateThumbnails, data: { id: 'asset-1', source: 'upload' } }, - jobs: [JobName.SmartSearch, JobName.FaceDetection], + item: { name: JobName.AssetGenerateThumbnails, data: { id: 'asset-1', source: 'upload' } }, + jobs: [JobName.SmartSearch, JobName.AssetDetectFaces], stub: [assetStub.livePhotoStillAsset], }, { - item: { name: JobName.GenerateThumbnails, data: { id: 'asset-1', source: 'upload' } }, - jobs: [JobName.SmartSearch, JobName.FaceDetection, JobName.VideoConversation], + item: { name: JobName.AssetGenerateThumbnails, data: { id: 'asset-1', source: 'upload' } }, + jobs: [JobName.SmartSearch, JobName.AssetDetectFaces, JobName.AssetEncodeVideo], stub: [assetStub.video], }, { @@ -276,7 +282,7 @@ describe(JobService.name, () => { jobs: [], }, { - item: { name: JobName.FaceDetection, data: { id: 'asset-1' } }, + item: { name: JobName.AssetDetectFaces, data: { id: 'asset-1' } }, jobs: [], }, { diff --git a/server/src/services/job.service.ts b/server/src/services/job.service.ts index 73254b9f38..c67f3af39f 100644 --- a/server/src/services/job.service.ts +++ b/server/src/services/job.service.ts @@ -40,15 +40,15 @@ const asJobItem = (dto: JobCreateDto): JobItem => { } case ManualJobName.MemoryCleanup: { - return { name: JobName.MemoriesCleanup }; + return { name: JobName.MemoryCleanup }; } case ManualJobName.MemoryCreate: { - return { name: JobName.MemoriesCreate }; + return { name: JobName.MemoryGenerate }; } case ManualJobName.BackupDatabase: { - return { name: JobName.BackupDatabase }; + return { name: JobName.DatabaseBackup }; } default: { @@ -190,7 +190,7 @@ export class JobService extends BaseService { switch (name) { case QueueName.VideoConversion: { - return this.jobRepository.queue({ name: JobName.QueueVideoConversion, data: { force } }); + return this.jobRepository.queue({ name: JobName.AssetEncodeVideoQueueAll, data: { force } }); } case QueueName.StorageTemplateMigration: { @@ -198,43 +198,43 @@ export class JobService extends BaseService { } case QueueName.Migration: { - return this.jobRepository.queue({ name: JobName.QueueMigration }); + return this.jobRepository.queue({ name: JobName.FileMigrationQueueAll }); } case QueueName.SmartSearch: { - return this.jobRepository.queue({ name: JobName.QueueSmartSearch, data: { force } }); + return this.jobRepository.queue({ name: JobName.SmartSearchQueueAll, data: { force } }); } case QueueName.DuplicateDetection: { - return this.jobRepository.queue({ name: JobName.QueueDuplicateDetection, data: { force } }); + return this.jobRepository.queue({ name: JobName.AssetDetectDuplicatesQueueAll, data: { force } }); } case QueueName.MetadataExtraction: { - return this.jobRepository.queue({ name: JobName.QueueMetadataExtraction, data: { force } }); + return this.jobRepository.queue({ name: JobName.AssetExtractMetadataQueueAll, data: { force } }); } case QueueName.Sidecar: { - return this.jobRepository.queue({ name: JobName.QueueSidecar, data: { force } }); + return this.jobRepository.queue({ name: JobName.SidecarQueueAll, data: { force } }); } case QueueName.ThumbnailGeneration: { - return this.jobRepository.queue({ name: JobName.QueueGenerateThumbnails, data: { force } }); + return this.jobRepository.queue({ name: JobName.AssetGenerateThumbnailsQueueAll, data: { force } }); } case QueueName.FaceDetection: { - return this.jobRepository.queue({ name: JobName.QueueFaceDetection, data: { force } }); + return this.jobRepository.queue({ name: JobName.AssetDetectFacesQueueAll, data: { force } }); } case QueueName.FacialRecognition: { - return this.jobRepository.queue({ name: JobName.QueueFacialRecognition, data: { force } }); + return this.jobRepository.queue({ name: JobName.FacialRecognitionQueueAll, data: { force } }); } case QueueName.Library: { - return this.jobRepository.queue({ name: JobName.LibraryQueueScanAll, data: { force } }); + return this.jobRepository.queue({ name: JobName.LibraryScanQueueAll, data: { force } }); } case QueueName.BackupDatabase: { - return this.jobRepository.queue({ name: JobName.BackupDatabase, data: { force } }); + return this.jobRepository.queue({ name: JobName.DatabaseBackup, data: { force } }); } default: { @@ -249,7 +249,7 @@ export class JobService extends BaseService { this.telemetryRepository.jobs.addToGauge(queueMetric, 1); try { const status = await this.jobRepository.run(job); - const jobMetric = `immich.jobs.${job.name.replaceAll('-', '_')}.${status}`; + const jobMetric = `immich.jobs.${snakeCase(job.name)}.${status}`; this.telemetryRepository.jobs.addToCounter(jobMetric, 1); if (status === JobStatus.Success || status == JobStatus.Skipped) { await this.onDone(job); @@ -276,29 +276,29 @@ export class JobService extends BaseService { if (config.nightlyTasks.databaseCleanup) { jobs.push( - { name: JobName.AssetDeletionCheck }, + { name: JobName.AssetDeleteCheck }, { name: JobName.UserDeleteCheck }, { name: JobName.PersonCleanup }, - { name: JobName.MemoriesCleanup }, - { name: JobName.CleanOldSessionTokens }, - { name: JobName.CleanOldAuditLogs }, + { name: JobName.MemoryCleanup }, + { name: JobName.SessionCleanup }, + { name: JobName.AuditLogCleanup }, ); } if (config.nightlyTasks.generateMemories) { - jobs.push({ name: JobName.MemoriesCreate }); + jobs.push({ name: JobName.MemoryGenerate }); } if (config.nightlyTasks.syncQuotaUsage) { - jobs.push({ name: JobName.userSyncUsage }); + jobs.push({ name: JobName.UserSyncUsage }); } if (config.nightlyTasks.missingThumbnails) { - jobs.push({ name: JobName.QueueGenerateThumbnails, data: { force: false } }); + jobs.push({ name: JobName.AssetGenerateThumbnailsQueueAll, data: { force: false } }); } if (config.nightlyTasks.clusterNewFaces) { - jobs.push({ name: JobName.QueueFacialRecognition, data: { force: false, nightly: true } }); + jobs.push({ name: JobName.FacialRecognitionQueueAll, data: { force: false, nightly: true } }); } await this.jobRepository.queueAll(jobs); @@ -311,13 +311,13 @@ export class JobService extends BaseService { switch (item.name) { case JobName.SidecarSync: case JobName.SidecarDiscovery: { - await this.jobRepository.queue({ name: JobName.MetadataExtraction, data: item.data }); + await this.jobRepository.queue({ name: JobName.AssetExtractMetadata, data: item.data }); break; } case JobName.SidecarWrite: { await this.jobRepository.queue({ - name: JobName.MetadataExtraction, + name: JobName.AssetExtractMetadata, data: { id: item.data.id, source: 'sidecar-write' }, }); break; @@ -325,12 +325,12 @@ export class JobService extends BaseService { case JobName.StorageTemplateMigrationSingle: { if (item.data.source === 'upload' || item.data.source === 'copy') { - await this.jobRepository.queue({ name: JobName.GenerateThumbnails, data: item.data }); + await this.jobRepository.queue({ name: JobName.AssetGenerateThumbnails, data: item.data }); } break; } - case JobName.GeneratePersonThumbnail: { + case JobName.PersonGenerateThumbnail: { const { id } = item.data; const person = await this.personRepository.getById(id); if (person) { @@ -339,7 +339,7 @@ export class JobService extends BaseService { break; } - case JobName.GenerateThumbnails: { + case JobName.AssetGenerateThumbnails: { if (!item.data.notify && item.data.source !== 'upload') { break; } @@ -352,11 +352,11 @@ export class JobService extends BaseService { const jobs: JobItem[] = [ { name: JobName.SmartSearch, data: item.data }, - { name: JobName.FaceDetection, data: item.data }, + { name: JobName.AssetDetectFaces, data: item.data }, ]; if (asset.type === AssetType.Video) { - jobs.push({ name: JobName.VideoConversation, data: item.data }); + jobs.push({ name: JobName.AssetEncodeVideo, data: item.data }); } await this.jobRepository.queueAll(jobs); @@ -419,12 +419,12 @@ export class JobService extends BaseService { case JobName.SmartSearch: { if (item.data.source === 'upload') { - await this.jobRepository.queue({ name: JobName.DuplicateDetection, data: item.data }); + await this.jobRepository.queue({ name: JobName.AssetDetectDuplicates, data: item.data }); } break; } - case JobName.UserDeletion: { + case JobName.UserDelete: { this.eventRepository.clientBroadcast('on_user_delete', item.data.id); break; } diff --git a/server/src/services/library.service.spec.ts b/server/src/services/library.service.spec.ts index aa2b80d928..dac2b64ebc 100644 --- a/server/src/services/library.service.spec.ts +++ b/server/src/services/library.service.spec.ts @@ -1010,7 +1010,7 @@ describe(LibraryService.name, () => { await sut.watchAll(); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.LibraryAssetRemoval, + name: JobName.LibraryRemoveAsset, data: { libraryId: library.id, paths: [assetStub.image.originalPath], @@ -1131,11 +1131,11 @@ describe(LibraryService.name, () => { expect(mocks.job.queue).toHaveBeenCalledTimes(2); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.LibraryQueueSyncFiles, + name: JobName.LibrarySyncFilesQueueAll, data: { id: library.id }, }); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.LibraryQueueSyncAssets, + name: JobName.LibrarySyncAssetsQueueAll, data: { id: library.id }, }); }); @@ -1150,11 +1150,11 @@ describe(LibraryService.name, () => { await expect(sut.handleQueueScanAll()).resolves.toBe(JobStatus.Success); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.LibraryQueueCleanup, + name: JobName.LibraryDeleteCheck, data: {}, }); expect(mocks.job.queueAll).toHaveBeenCalledWith([ - { name: JobName.LibraryQueueSyncFiles, data: { id: library.id } }, + { name: JobName.LibrarySyncFilesQueueAll, data: { id: library.id } }, ]); }); }); diff --git a/server/src/services/library.service.ts b/server/src/services/library.service.ts index f8377081fa..4c96ad0062 100644 --- a/server/src/services/library.service.ts +++ b/server/src/services/library.service.ts @@ -47,7 +47,7 @@ export class LibraryService extends BaseService { this.cronRepository.create({ name: CronJob.LibraryScan, expression: scan.cronExpression, - onTick: () => handlePromiseError(this.jobRepository.queue({ name: JobName.LibraryQueueScanAll }), this.logger), + onTick: () => handlePromiseError(this.jobRepository.queue({ name: JobName.LibraryScanQueueAll }), this.logger), start: scan.enabled, }); } @@ -113,7 +113,7 @@ export class LibraryService extends BaseService { const deletionHandler = async (path: string) => { this.logger.debug(`File unlink event received for ${path} in library ${library.id}}`); await this.jobRepository.queue({ - name: JobName.LibraryAssetRemoval, + name: JobName.LibraryRemoveAsset, data: { libraryId: library.id, paths: [path] }, }); }; @@ -198,7 +198,7 @@ export class LibraryService extends BaseService { return libraries.map((library) => mapLibrary(library)); } - @OnJob({ name: JobName.LibraryQueueCleanup, queue: QueueName.Library }) + @OnJob({ name: JobName.LibraryDeleteCheck, queue: QueueName.Library }) async handleQueueCleanup(): Promise { this.logger.log('Checking for any libraries pending deletion...'); const pendingDeletions = await this.libraryRepository.getAllDeleted(); @@ -355,7 +355,7 @@ export class LibraryService extends BaseService { assetsFound = true; this.logger.debug(`Queueing deletion of ${chunk.length} asset(s) in library ${libraryId}`); await this.jobRepository.queueAll( - chunk.map((id) => ({ name: JobName.AssetDeletion, data: { id, deleteOnDisk: false } })), + chunk.map((id) => ({ name: JobName.AssetDelete, data: { id, deleteOnDisk: false } })), ); chunk = []; } @@ -422,30 +422,30 @@ export class LibraryService extends BaseService { this.logger.log(`Starting to scan library ${id}`); await this.jobRepository.queue({ - name: JobName.LibraryQueueSyncFiles, + name: JobName.LibrarySyncFilesQueueAll, data: { id, }, }); - await this.jobRepository.queue({ name: JobName.LibraryQueueSyncAssets, data: { id } }); + await this.jobRepository.queue({ name: JobName.LibrarySyncAssetsQueueAll, data: { id } }); } async queueScanAll() { - await this.jobRepository.queue({ name: JobName.LibraryQueueScanAll, data: {} }); + await this.jobRepository.queue({ name: JobName.LibraryScanQueueAll, data: {} }); } - @OnJob({ name: JobName.LibraryQueueScanAll, queue: QueueName.Library }) + @OnJob({ name: JobName.LibraryScanQueueAll, queue: QueueName.Library }) async handleQueueScanAll(): Promise { this.logger.log(`Initiating scan of all external libraries...`); - await this.jobRepository.queue({ name: JobName.LibraryQueueCleanup, data: {} }); + await this.jobRepository.queue({ name: JobName.LibraryDeleteCheck, data: {} }); const libraries = await this.libraryRepository.getAll(true); await this.jobRepository.queueAll( libraries.map((library) => ({ - name: JobName.LibraryQueueSyncFiles, + name: JobName.LibrarySyncFilesQueueAll, data: { id: library.id, }, @@ -453,7 +453,7 @@ export class LibraryService extends BaseService { ); await this.jobRepository.queueAll( libraries.map((library) => ({ - name: JobName.LibraryQueueSyncAssets, + name: JobName.LibrarySyncAssetsQueueAll, data: { id: library.id, }, @@ -598,8 +598,8 @@ export class LibraryService extends BaseService { return AssetSyncResult.DO_NOTHING; } - @OnJob({ name: JobName.LibraryQueueSyncFiles, queue: QueueName.Library }) - async handleQueueSyncFiles(job: JobOf): Promise { + @OnJob({ name: JobName.LibrarySyncFilesQueueAll, queue: QueueName.Library }) + async handleQueueSyncFiles(job: JobOf): Promise { const library = await this.libraryRepository.get(job.id); if (!library) { this.logger.debug(`Library ${job.id} not found, skipping refresh`); @@ -668,8 +668,8 @@ export class LibraryService extends BaseService { return JobStatus.Success; } - @OnJob({ name: JobName.LibraryAssetRemoval, queue: QueueName.Library }) - async handleAssetRemoval(job: JobOf): Promise { + @OnJob({ name: JobName.LibraryRemoveAsset, queue: QueueName.Library }) + async handleAssetRemoval(job: JobOf): Promise { // This is only for handling file unlink events via the file watcher this.logger.verbose(`Deleting asset(s) ${job.paths} from library ${job.libraryId}`); for (const assetPath of job.paths) { @@ -682,8 +682,8 @@ export class LibraryService extends BaseService { return JobStatus.Success; } - @OnJob({ name: JobName.LibraryQueueSyncAssets, queue: QueueName.Library }) - async handleQueueSyncAssets(job: JobOf): Promise { + @OnJob({ name: JobName.LibrarySyncAssetsQueueAll, queue: QueueName.Library }) + async handleQueueSyncAssets(job: JobOf): Promise { const library = await this.libraryRepository.get(job.id); if (!library) { return JobStatus.Skipped; diff --git a/server/src/services/media.service.spec.ts b/server/src/services/media.service.spec.ts index f535bb65ff..d3c361bb8a 100644 --- a/server/src/services/media.service.spec.ts +++ b/server/src/services/media.service.spec.ts @@ -49,7 +49,7 @@ describe(MediaService.name, () => { expect(mocks.assetJob.streamForThumbnailJob).toHaveBeenCalledWith(true); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.GenerateThumbnails, + name: JobName.AssetGenerateThumbnails, data: { id: assetStub.image.id }, }, ]); @@ -57,7 +57,7 @@ describe(MediaService.name, () => { expect(mocks.person.getAll).toHaveBeenCalledWith(undefined); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.GeneratePersonThumbnail, + name: JobName.PersonGenerateThumbnail, data: { id: personStub.newThumbnail.id }, }, ]); @@ -72,7 +72,7 @@ describe(MediaService.name, () => { expect(mocks.assetJob.streamForThumbnailJob).toHaveBeenCalledWith(true); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.GenerateThumbnails, + name: JobName.AssetGenerateThumbnails, data: { id: assetStub.trashed.id }, }, ]); @@ -87,7 +87,7 @@ describe(MediaService.name, () => { expect(mocks.assetJob.streamForThumbnailJob).toHaveBeenCalledWith(true); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.GenerateThumbnails, + name: JobName.AssetGenerateThumbnails, data: { id: assetStub.archived.id }, }, ]); @@ -106,7 +106,7 @@ describe(MediaService.name, () => { expect(mocks.person.update).toHaveBeenCalledTimes(1); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.GeneratePersonThumbnail, + name: JobName.PersonGenerateThumbnail, data: { id: personStub.newThumbnail.id, }, @@ -122,7 +122,7 @@ describe(MediaService.name, () => { expect(mocks.assetJob.streamForThumbnailJob).toHaveBeenCalledWith(false); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.GenerateThumbnails, + name: JobName.AssetGenerateThumbnails, data: { id: assetStub.image.id }, }, ]); @@ -138,7 +138,7 @@ describe(MediaService.name, () => { expect(mocks.assetJob.streamForThumbnailJob).toHaveBeenCalledWith(false); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.GenerateThumbnails, + name: JobName.AssetGenerateThumbnails, data: { id: assetStub.image.id }, }, ]); @@ -154,7 +154,7 @@ describe(MediaService.name, () => { expect(mocks.assetJob.streamForThumbnailJob).toHaveBeenCalledWith(false); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.GenerateThumbnails, + name: JobName.AssetGenerateThumbnails, data: { id: assetStub.image.id }, }, ]); @@ -173,10 +173,10 @@ describe(MediaService.name, () => { expect(mocks.storage.removeEmptyDirs).toHaveBeenCalledTimes(2); expect(mocks.job.queueAll).toHaveBeenCalledWith([ - { name: JobName.MigrateAsset, data: { id: assetStub.image.id } }, + { name: JobName.AssetFileMigration, data: { id: assetStub.image.id } }, ]); expect(mocks.job.queueAll).toHaveBeenCalledWith([ - { name: JobName.MigratePerson, data: { id: personStub.withName.id } }, + { name: JobName.PersonFileMigration, data: { id: personStub.withName.id } }, ]); }); }); @@ -1243,7 +1243,7 @@ describe(MediaService.name, () => { expect(mocks.assetJob.streamForVideoConversion).toHaveBeenCalledWith(true); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.VideoConversation, + name: JobName.AssetEncodeVideo, data: { id: assetStub.video.id }, }, ]); @@ -1257,7 +1257,7 @@ describe(MediaService.name, () => { expect(mocks.assetJob.streamForVideoConversion).toHaveBeenCalledWith(void 0); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.VideoConversation, + name: JobName.AssetEncodeVideo, data: { id: assetStub.video.id }, }, ]); @@ -1616,7 +1616,7 @@ describe(MediaService.name, () => { expect(mocks.media.transcode).not.toHaveBeenCalled(); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.DeleteFiles, + name: JobName.FileDelete, data: { files: [asset.encodedVideoPath] }, }); }); diff --git a/server/src/services/media.service.ts b/server/src/services/media.service.ts index b48df3797a..a2c3c5ed42 100644 --- a/server/src/services/media.service.ts +++ b/server/src/services/media.service.ts @@ -57,8 +57,8 @@ export class MediaService extends BaseService { this.videoInterfaces = { dri, mali }; } - @OnJob({ name: JobName.QueueGenerateThumbnails, queue: QueueName.ThumbnailGeneration }) - async handleQueueGenerateThumbnails({ force }: JobOf): Promise { + @OnJob({ name: JobName.AssetGenerateThumbnailsQueueAll, queue: QueueName.ThumbnailGeneration }) + async handleQueueGenerateThumbnails({ force }: JobOf): Promise { let jobs: JobItem[] = []; const queueAll = async () => { @@ -70,7 +70,7 @@ export class MediaService extends BaseService { const { previewFile, thumbnailFile } = getAssetFiles(asset.files); if (!previewFile || !thumbnailFile || !asset.thumbhash || force) { - jobs.push({ name: JobName.GenerateThumbnails, data: { id: asset.id } }); + jobs.push({ name: JobName.AssetGenerateThumbnails, data: { id: asset.id } }); } if (jobs.length >= JOBS_ASSET_PAGINATION_SIZE) { @@ -92,7 +92,7 @@ export class MediaService extends BaseService { await this.personRepository.update({ id: person.id, faceAssetId: face.id }); } - jobs.push({ name: JobName.GeneratePersonThumbnail, data: { id: person.id } }); + jobs.push({ name: JobName.PersonGenerateThumbnail, data: { id: person.id } }); if (jobs.length >= JOBS_ASSET_PAGINATION_SIZE) { await queueAll(); } @@ -103,7 +103,7 @@ export class MediaService extends BaseService { return JobStatus.Success; } - @OnJob({ name: JobName.QueueMigration, queue: QueueName.Migration }) + @OnJob({ name: JobName.FileMigrationQueueAll, queue: QueueName.Migration }) async handleQueueMigration(): Promise { const { active, waiting } = await this.jobRepository.getJobCounts(QueueName.Migration); if (active === 1 && waiting === 0) { @@ -114,7 +114,7 @@ export class MediaService extends BaseService { let jobs: JobItem[] = []; const assets = this.assetJobRepository.streamForMigrationJob(); for await (const asset of assets) { - jobs.push({ name: JobName.MigrateAsset, data: { id: asset.id } }); + jobs.push({ name: JobName.AssetFileMigration, data: { id: asset.id } }); if (jobs.length >= JOBS_ASSET_PAGINATION_SIZE) { await this.jobRepository.queueAll(jobs); jobs = []; @@ -125,7 +125,7 @@ export class MediaService extends BaseService { jobs = []; for await (const person of this.personRepository.getAll()) { - jobs.push({ name: JobName.MigratePerson, data: { id: person.id } }); + jobs.push({ name: JobName.PersonFileMigration, data: { id: person.id } }); if (jobs.length === JOBS_ASSET_PAGINATION_SIZE) { await this.jobRepository.queueAll(jobs); @@ -138,8 +138,8 @@ export class MediaService extends BaseService { return JobStatus.Success; } - @OnJob({ name: JobName.MigrateAsset, queue: QueueName.Migration }) - async handleAssetMigration({ id }: JobOf): Promise { + @OnJob({ name: JobName.AssetFileMigration, queue: QueueName.Migration }) + async handleAssetMigration({ id }: JobOf): Promise { const { image } = await this.getConfig({ withCache: true }); const asset = await this.assetJobRepository.getForMigrationJob(id); if (!asset) { @@ -154,8 +154,8 @@ export class MediaService extends BaseService { return JobStatus.Success; } - @OnJob({ name: JobName.GenerateThumbnails, queue: QueueName.ThumbnailGeneration }) - async handleGenerateThumbnails({ id }: JobOf): Promise { + @OnJob({ name: JobName.AssetGenerateThumbnails, queue: QueueName.ThumbnailGeneration }) + async handleGenerateThumbnails({ id }: JobOf): Promise { const asset = await this.assetJobRepository.getForGenerateThumbnailJob(id); if (!asset) { this.logger.warn(`Thumbnail generation failed for asset ${id}: not found`); @@ -317,8 +317,8 @@ export class MediaService extends BaseService { return { previewPath, thumbnailPath, fullsizePath, thumbhash: outputs[0] as Buffer }; } - @OnJob({ name: JobName.GeneratePersonThumbnail, queue: QueueName.ThumbnailGeneration }) - async handleGeneratePersonThumbnail({ id }: JobOf): Promise { + @OnJob({ name: JobName.PersonGenerateThumbnail, queue: QueueName.ThumbnailGeneration }) + async handleGeneratePersonThumbnail({ id }: JobOf): Promise { const { machineLearning, metadata, image } = await this.getConfig({ withCache: true }); if (!isFacialRecognitionEnabled(machineLearning) && !isFaceImportEnabled(metadata)) { return JobStatus.Skipped; @@ -443,13 +443,13 @@ export class MediaService extends BaseService { return { previewPath, thumbnailPath, thumbhash }; } - @OnJob({ name: JobName.QueueVideoConversion, queue: QueueName.VideoConversion }) - async handleQueueVideoConversion(job: JobOf): Promise { + @OnJob({ name: JobName.AssetEncodeVideoQueueAll, queue: QueueName.VideoConversion }) + async handleQueueVideoConversion(job: JobOf): Promise { const { force } = job; - let queue: { name: JobName.VideoConversation; data: { id: string } }[] = []; + let queue: { name: JobName.AssetEncodeVideo; data: { id: string } }[] = []; for await (const asset of this.assetJobRepository.streamForVideoConversion(force)) { - queue.push({ name: JobName.VideoConversation, data: { id: asset.id } }); + queue.push({ name: JobName.AssetEncodeVideo, data: { id: asset.id } }); if (queue.length >= JOBS_ASSET_PAGINATION_SIZE) { await this.jobRepository.queueAll(queue); @@ -462,8 +462,8 @@ export class MediaService extends BaseService { return JobStatus.Success; } - @OnJob({ name: JobName.VideoConversation, queue: QueueName.VideoConversion }) - async handleVideoConversion({ id }: JobOf): Promise { + @OnJob({ name: JobName.AssetEncodeVideo, queue: QueueName.VideoConversion }) + async handleVideoConversion({ id }: JobOf): Promise { const asset = await this.assetJobRepository.getForVideoConversion(id); if (!asset) { return JobStatus.Failed; @@ -492,7 +492,7 @@ export class MediaService extends BaseService { if (target === TranscodeTarget.None && !this.isRemuxRequired(ffmpeg, format)) { if (asset.encodedVideoPath) { this.logger.log(`Transcoded video exists for asset ${asset.id}, but is no longer required. Deleting...`); - await this.jobRepository.queue({ name: JobName.DeleteFiles, data: { files: [asset.encodedVideoPath] } }); + await this.jobRepository.queue({ name: JobName.FileDelete, data: { files: [asset.encodedVideoPath] } }); await this.assetRepository.update({ id: asset.id, encodedVideoPath: null }); } else { this.logger.verbose(`Asset ${asset.id} does not require transcoding based on current policy, skipping`); diff --git a/server/src/services/memory.service.ts b/server/src/services/memory.service.ts index ff88b9029c..7bf9deab4b 100644 --- a/server/src/services/memory.service.ts +++ b/server/src/services/memory.service.ts @@ -12,7 +12,7 @@ const DAYS = 3; @Injectable() export class MemoryService extends BaseService { - @OnJob({ name: JobName.MemoriesCreate, queue: QueueName.BackgroundTask }) + @OnJob({ name: JobName.MemoryGenerate, queue: QueueName.BackgroundTask }) async onMemoriesCreate() { const users = await this.userRepository.getList({ withDeleted: false }); const usersIds = await Promise.all( @@ -72,7 +72,7 @@ export class MemoryService extends BaseService { ); } - @OnJob({ name: JobName.MemoriesCleanup, queue: QueueName.BackgroundTask }) + @OnJob({ name: JobName.MemoryCleanup, queue: QueueName.BackgroundTask }) async onMemoriesCleanup() { await this.memoryRepository.cleanup(); } diff --git a/server/src/services/metadata.service.spec.ts b/server/src/services/metadata.service.spec.ts index 23884256ea..77f0b50a0a 100644 --- a/server/src/services/metadata.service.spec.ts +++ b/server/src/services/metadata.service.spec.ts @@ -106,7 +106,7 @@ describe(MetadataService.name, () => { expect(mocks.assetJob.streamForMetadataExtraction).toHaveBeenCalledWith(false); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.MetadataExtraction, + name: JobName.AssetExtractMetadata, data: { id: assetStub.image.id }, }, ]); @@ -119,7 +119,7 @@ describe(MetadataService.name, () => { expect(mocks.assetJob.streamForMetadataExtraction).toHaveBeenCalledWith(true); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.MetadataExtraction, + name: JobName.AssetExtractMetadata, data: { id: assetStub.image.id }, }, ]); @@ -599,7 +599,7 @@ describe(MetadataService.name, () => { }); expect(mocks.asset.update).toHaveBeenCalledTimes(3); expect(mocks.job.queue).toHaveBeenCalledExactlyOnceWith({ - name: JobName.VideoConversation, + name: JobName.AssetEncodeVideo, data: { id: assetStub.livePhotoMotionAsset.id }, }); }); @@ -657,7 +657,7 @@ describe(MetadataService.name, () => { }); expect(mocks.asset.update).toHaveBeenCalledTimes(3); expect(mocks.job.queue).toHaveBeenCalledExactlyOnceWith({ - name: JobName.VideoConversation, + name: JobName.AssetEncodeVideo, data: { id: assetStub.livePhotoMotionAsset.id }, }); }); @@ -715,7 +715,7 @@ describe(MetadataService.name, () => { }); expect(mocks.asset.update).toHaveBeenCalledTimes(3); expect(mocks.job.queue).toHaveBeenCalledExactlyOnceWith({ - name: JobName.VideoConversation, + name: JobName.AssetEncodeVideo, data: { id: assetStub.livePhotoMotionAsset.id }, }); }); @@ -737,7 +737,7 @@ describe(MetadataService.name, () => { await sut.handleMetadataExtraction({ id: assetStub.livePhotoWithOriginalFileName.id }); expect(mocks.job.queue).toHaveBeenNthCalledWith(1, { - name: JobName.AssetDeletion, + name: JobName.AssetDelete, data: { id: assetStub.livePhotoWithOriginalFileName.livePhotoVideoId, deleteOnDisk: true }, }); }); @@ -1116,7 +1116,7 @@ describe(MetadataService.name, () => { ]); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.GeneratePersonThumbnail, + name: JobName.PersonGenerateThumbnail, data: { id: personStub.withName.id }, }, ]); @@ -1244,7 +1244,7 @@ describe(MetadataService.name, () => { ]); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.GeneratePersonThumbnail, + name: JobName.PersonGenerateThumbnail, data: { id: personStub.withName.id }, }, ]); diff --git a/server/src/services/metadata.service.ts b/server/src/services/metadata.service.ts index 037bab3633..32a3d98f4e 100644 --- a/server/src/services/metadata.service.ts +++ b/server/src/services/metadata.service.ts @@ -193,13 +193,13 @@ export class MetadataService extends BaseService { await this.eventRepository.emit('AssetHide', { assetId: motionAsset.id, userId: motionAsset.ownerId }); } - @OnJob({ name: JobName.QueueMetadataExtraction, queue: QueueName.MetadataExtraction }) - async handleQueueMetadataExtraction(job: JobOf): Promise { + @OnJob({ name: JobName.AssetExtractMetadataQueueAll, queue: QueueName.MetadataExtraction }) + async handleQueueMetadataExtraction(job: JobOf): Promise { const { force } = job; - let queue: { name: JobName.MetadataExtraction; data: { id: string } }[] = []; + let queue: { name: JobName.AssetExtractMetadata; data: { id: string } }[] = []; for await (const asset of this.assetJobRepository.streamForMetadataExtraction(force)) { - queue.push({ name: JobName.MetadataExtraction, data: { id: asset.id } }); + queue.push({ name: JobName.AssetExtractMetadata, data: { id: asset.id } }); if (queue.length >= JOBS_ASSET_PAGINATION_SIZE) { await this.jobRepository.queueAll(queue); @@ -211,8 +211,8 @@ export class MetadataService extends BaseService { return JobStatus.Success; } - @OnJob({ name: JobName.MetadataExtraction, queue: QueueName.MetadataExtraction }) - async handleMetadataExtraction(data: JobOf) { + @OnJob({ name: JobName.AssetExtractMetadata, queue: QueueName.MetadataExtraction }) + async handleMetadataExtraction(data: JobOf) { const [{ metadata, reverseGeocoding }, asset] = await Promise.all([ this.getConfig({ withCache: true }), this.assetJobRepository.getForMetadataExtraction(data.id), @@ -320,8 +320,8 @@ export class MetadataService extends BaseService { }); } - @OnJob({ name: JobName.QueueSidecar, queue: QueueName.Sidecar }) - async handleQueueSidecar({ force }: JobOf): Promise { + @OnJob({ name: JobName.SidecarQueueAll, queue: QueueName.Sidecar }) + async handleQueueSidecar({ force }: JobOf): Promise { let jobs: JobItem[] = []; const queueAll = async () => { await this.jobRepository.queueAll(jobs); @@ -597,7 +597,7 @@ export class MetadataService extends BaseService { // note asset.livePhotoVideoId is not motionAsset.id yet if (asset.livePhotoVideoId) { await this.jobRepository.queue({ - name: JobName.AssetDeletion, + name: JobName.AssetDelete, data: { id: asset.livePhotoVideoId, deleteOnDisk: true }, }); this.logger.log(`Removed old motion photo video asset (${asset.livePhotoVideoId})`); @@ -612,7 +612,7 @@ export class MetadataService extends BaseService { this.logger.log(`Wrote motion photo video to ${motionAsset.originalPath}`); await this.handleMetadataExtraction({ id: motionAsset.id }); - await this.jobRepository.queue({ name: JobName.VideoConversation, data: { id: motionAsset.id } }); + await this.jobRepository.queue({ name: JobName.AssetEncodeVideo, data: { id: motionAsset.id } }); } this.logger.debug(`Finished motion photo video extraction for asset ${asset.id}: ${asset.originalPath}`); @@ -753,7 +753,7 @@ export class MetadataService extends BaseService { if (missing.length > 0) { this.logger.debugFn(() => `Creating missing persons: ${missing.map((p) => `${p.name}/${p.id}`)}`); const newPersonIds = await this.personRepository.createAll(missing); - const jobs = newPersonIds.map((id) => ({ name: JobName.GeneratePersonThumbnail, data: { id } }) as const); + const jobs = newPersonIds.map((id) => ({ name: JobName.PersonGenerateThumbnail, data: { id } }) as const); await this.jobRepository.queueAll(jobs); } diff --git a/server/src/services/notification.service.spec.ts b/server/src/services/notification.service.spec.ts index 97e5ddf106..eef1c4f8b2 100644 --- a/server/src/services/notification.service.spec.ts +++ b/server/src/services/notification.service.spec.ts @@ -131,7 +131,7 @@ describe(NotificationService.name, () => { it('should queue the generate thumbnail job', async () => { await sut.onAssetShow({ assetId: 'asset-id', userId: 'user-id' }); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.GenerateThumbnails, + name: JobName.AssetGenerateThumbnails, data: { id: 'asset-id', notify: true }, }); }); @@ -146,7 +146,7 @@ describe(NotificationService.name, () => { it('should queue notify signup event if notify is true', async () => { await sut.onUserSignup({ id: '', notify: true }); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.NotifySignup, + name: JobName.NotifyUserSignup, data: { id: '', tempPassword: undefined }, }); }); diff --git a/server/src/services/notification.service.ts b/server/src/services/notification.service.ts index 90a3b63ac5..1a257309b2 100644 --- a/server/src/services/notification.service.ts +++ b/server/src/services/notification.service.ts @@ -87,7 +87,7 @@ export class NotificationService extends BaseService { this.logger.error(`Unable to run job handler (${job.name}): ${error}`, error?.stack, JSON.stringify(job.data)); switch (job.name) { - case JobName.BackupDatabase: { + case JobName.DatabaseBackup: { const errorMessage = error instanceof Error ? error.message : error; const item = await this.notificationRepository.create({ userId: admin.id, @@ -135,7 +135,7 @@ export class NotificationService extends BaseService { @OnEvent({ name: 'AssetShow' }) async onAssetShow({ assetId }: ArgOf<'AssetShow'>) { - await this.jobRepository.queue({ name: JobName.GenerateThumbnails, data: { id: assetId, notify: true } }); + await this.jobRepository.queue({ name: JobName.AssetGenerateThumbnails, data: { id: assetId, notify: true } }); } @OnEvent({ name: 'AssetTrash' }) @@ -193,7 +193,7 @@ export class NotificationService extends BaseService { @OnEvent({ name: 'UserSignup' }) async onUserSignup({ notify, id, tempPassword }: ArgOf<'UserSignup'>) { if (notify) { - await this.jobRepository.queue({ name: JobName.NotifySignup, data: { id, tempPassword } }); + await this.jobRepository.queue({ name: JobName.NotifyUserSignup, data: { id, tempPassword } }); } } @@ -313,8 +313,8 @@ export class NotificationService extends BaseService { return { name, html: templateResponse }; } - @OnJob({ name: JobName.NotifySignup, queue: QueueName.Notification }) - async handleUserSignup({ id, tempPassword }: JobOf) { + @OnJob({ name: JobName.NotifyUserSignup, queue: QueueName.Notification }) + async handleUserSignup({ id, tempPassword }: JobOf) { const user = await this.userRepository.get(id, { withDeleted: false }); if (!user) { return JobStatus.Skipped; diff --git a/server/src/services/person.service.spec.ts b/server/src/services/person.service.spec.ts index 8fbf8b20dd..13c3128317 100644 --- a/server/src/services/person.service.spec.ts +++ b/server/src/services/person.service.spec.ts @@ -276,7 +276,7 @@ describe(PersonService.name, () => { }, ]); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.GeneratePersonThumbnail, + name: JobName.PersonGenerateThumbnail, data: { id: 'person-1' }, }); expect(mocks.access.person.checkOwnerAccess).toHaveBeenCalledWith(authStub.admin.user.id, new Set(['person-1'])); @@ -337,7 +337,7 @@ describe(PersonService.name, () => { expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.GeneratePersonThumbnail, + name: JobName.PersonGenerateThumbnail, data: { id: personStub.newThumbnail.id }, }, ]); @@ -373,7 +373,7 @@ describe(PersonService.name, () => { await sut.createNewFeaturePhoto([personStub.newThumbnail.id]); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.GeneratePersonThumbnail, + name: JobName.PersonGenerateThumbnail, data: { id: personStub.newThumbnail.id }, }, ]); @@ -462,7 +462,7 @@ describe(PersonService.name, () => { expect(mocks.person.vacuum).not.toHaveBeenCalled(); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.FaceDetection, + name: JobName.AssetDetectFaces, data: { id: assetStub.image.id }, }, ]); @@ -481,7 +481,7 @@ describe(PersonService.name, () => { expect(mocks.assetJob.streamForDetectFacesJob).toHaveBeenCalledWith(true); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.FaceDetection, + name: JobName.AssetDetectFaces, data: { id: assetStub.image.id }, }, ]); @@ -499,7 +499,7 @@ describe(PersonService.name, () => { expect(mocks.assetJob.streamForDetectFacesJob).toHaveBeenCalledWith(undefined); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.FaceDetection, + name: JobName.AssetDetectFaces, data: { id: assetStub.image.id }, }, ]); @@ -518,7 +518,7 @@ describe(PersonService.name, () => { expect(mocks.assetJob.streamForDetectFacesJob).toHaveBeenCalledWith(true); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.FaceDetection, + name: JobName.AssetDetectFaces, data: { id: assetStub.image.id }, }, ]); @@ -754,7 +754,7 @@ describe(PersonService.name, () => { expect(mocks.person.refreshFaces).toHaveBeenCalledWith([face], [], [faceSearch]); expect(mocks.job.queueAll).toHaveBeenCalledWith([ - { name: JobName.QueueFacialRecognition, data: { force: false } }, + { name: JobName.FacialRecognitionQueueAll, data: { force: false } }, { name: JobName.FacialRecognition, data: { id: faceId } }, ]); expect(mocks.person.reassignFace).not.toHaveBeenCalled(); @@ -790,7 +790,7 @@ describe(PersonService.name, () => { expect(mocks.person.refreshFaces).toHaveBeenCalledWith([face], [faceStub.primaryFace1.id], [faceSearch]); expect(mocks.job.queueAll).toHaveBeenCalledWith([ - { name: JobName.QueueFacialRecognition, data: { force: false } }, + { name: JobName.FacialRecognitionQueueAll, data: { force: false } }, { name: JobName.FacialRecognition, data: { id: faceId } }, ]); expect(mocks.person.reassignFace).not.toHaveBeenCalled(); @@ -830,7 +830,7 @@ describe(PersonService.name, () => { expect(mocks.person.refreshFaces).toHaveBeenCalledWith([face], [], [faceSearch]); expect(mocks.job.queueAll).toHaveBeenCalledWith([ - { name: JobName.QueueFacialRecognition, data: { force: false } }, + { name: JobName.FacialRecognitionQueueAll, data: { force: false } }, { name: JobName.FacialRecognition, data: { id: faceId } }, ]); expect(mocks.person.reassignFace).not.toHaveBeenCalled(); diff --git a/server/src/services/person.service.ts b/server/src/services/person.service.ts index d8925578d4..d0c43c3dad 100644 --- a/server/src/services/person.service.ts +++ b/server/src/services/person.service.ts @@ -140,7 +140,7 @@ export class PersonService extends BaseService { if (assetFace) { await this.personRepository.update({ id: personId, faceAssetId: assetFace.id }); - jobs.push({ name: JobName.GeneratePersonThumbnail, data: { id: personId } }); + jobs.push({ name: JobName.PersonGenerateThumbnail, data: { id: personId } }); } } @@ -211,7 +211,7 @@ export class PersonService extends BaseService { }); if (assetId) { - await this.jobRepository.queue({ name: JobName.GeneratePersonThumbnail, data: { id } }); + await this.jobRepository.queue({ name: JobName.PersonGenerateThumbnail, data: { id } }); } return mapPerson(person); @@ -261,8 +261,8 @@ export class PersonService extends BaseService { return JobStatus.Success; } - @OnJob({ name: JobName.QueueFaceDetection, queue: QueueName.FaceDetection }) - async handleQueueDetectFaces({ force }: JobOf): Promise { + @OnJob({ name: JobName.AssetDetectFacesQueueAll, queue: QueueName.FaceDetection }) + async handleQueueDetectFaces({ force }: JobOf): Promise { const { machineLearning } = await this.getConfig({ withCache: false }); if (!isFacialRecognitionEnabled(machineLearning)) { return JobStatus.Skipped; @@ -277,7 +277,7 @@ export class PersonService extends BaseService { let jobs: JobItem[] = []; const assets = this.assetJobRepository.streamForDetectFacesJob(force); for await (const asset of assets) { - jobs.push({ name: JobName.FaceDetection, data: { id: asset.id } }); + jobs.push({ name: JobName.AssetDetectFaces, data: { id: asset.id } }); if (jobs.length >= JOBS_ASSET_PAGINATION_SIZE) { await this.jobRepository.queueAll(jobs); @@ -294,8 +294,8 @@ export class PersonService extends BaseService { return JobStatus.Success; } - @OnJob({ name: JobName.FaceDetection, queue: QueueName.FaceDetection }) - async handleDetectFaces({ id }: JobOf): Promise { + @OnJob({ name: JobName.AssetDetectFaces, queue: QueueName.FaceDetection }) + async handleDetectFaces({ id }: JobOf): Promise { const { machineLearning } = await this.getConfig({ withCache: true }); if (!isFacialRecognitionEnabled(machineLearning)) { return JobStatus.Skipped; @@ -369,7 +369,7 @@ export class PersonService extends BaseService { if (facesToAdd.length > 0) { this.logger.log(`Detected ${facesToAdd.length} new faces in asset ${id}`); const jobs = facesToAdd.map((face) => ({ name: JobName.FacialRecognition, data: { id: face.id } }) as const); - await this.jobRepository.queueAll([{ name: JobName.QueueFacialRecognition, data: { force: false } }, ...jobs]); + await this.jobRepository.queueAll([{ name: JobName.FacialRecognitionQueueAll, data: { force: false } }, ...jobs]); } else if (embeddings.length > 0) { this.logger.log(`Added ${embeddings.length} face embeddings for asset ${id}`); } @@ -396,8 +396,8 @@ export class PersonService extends BaseService { return intersection / union; } - @OnJob({ name: JobName.QueueFacialRecognition, queue: QueueName.FacialRecognition }) - async handleQueueRecognizeFaces({ force, nightly }: JobOf): Promise { + @OnJob({ name: JobName.FacialRecognitionQueueAll, queue: QueueName.FacialRecognition }) + async handleQueueRecognizeFaces({ force, nightly }: JobOf): Promise { const { machineLearning } = await this.getConfig({ withCache: false }); if (!isFacialRecognitionEnabled(machineLearning)) { return JobStatus.Skipped; @@ -526,7 +526,7 @@ export class PersonService extends BaseService { if (isCore && !personId) { this.logger.log(`Creating new person for face ${id}`); const newPerson = await this.personRepository.create({ ownerId: face.asset.ownerId, faceAssetId: face.id }); - await this.jobRepository.queue({ name: JobName.GeneratePersonThumbnail, data: { id: newPerson.id } }); + await this.jobRepository.queue({ name: JobName.PersonGenerateThumbnail, data: { id: newPerson.id } }); personId = newPerson.id; } @@ -538,8 +538,8 @@ export class PersonService extends BaseService { return JobStatus.Success; } - @OnJob({ name: JobName.MigratePerson, queue: QueueName.Migration }) - async handlePersonMigration({ id }: JobOf): Promise { + @OnJob({ name: JobName.PersonFileMigration, queue: QueueName.Migration }) + async handlePersonMigration({ id }: JobOf): Promise { const person = await this.personRepository.getById(id); if (!person) { return JobStatus.Failed; diff --git a/server/src/services/session.service.ts b/server/src/services/session.service.ts index b7bb5cb6fa..a9c7e92fcb 100644 --- a/server/src/services/session.service.ts +++ b/server/src/services/session.service.ts @@ -14,7 +14,7 @@ import { BaseService } from 'src/services/base.service'; @Injectable() export class SessionService extends BaseService { - @OnJob({ name: JobName.CleanOldSessionTokens, queue: QueueName.BackgroundTask }) + @OnJob({ name: JobName.SessionCleanup, queue: QueueName.BackgroundTask }) async handleCleanup(): Promise { const sessions = await this.sessionRepository.cleanup(); for (const session of sessions) { diff --git a/server/src/services/smart-info.service.ts b/server/src/services/smart-info.service.ts index 5ce47593f4..3b8e2d1fc3 100644 --- a/server/src/services/smart-info.service.ts +++ b/server/src/services/smart-info.service.ts @@ -64,8 +64,8 @@ export class SmartInfoService extends BaseService { }); } - @OnJob({ name: JobName.QueueSmartSearch, queue: QueueName.SmartSearch }) - async handleQueueEncodeClip({ force }: JobOf): Promise { + @OnJob({ name: JobName.SmartSearchQueueAll, queue: QueueName.SmartSearch }) + async handleQueueEncodeClip({ force }: JobOf): Promise { const { machineLearning } = await this.getConfig({ withCache: false }); if (!isSmartSearchEnabled(machineLearning)) { return JobStatus.Skipped; diff --git a/server/src/services/storage.service.ts b/server/src/services/storage.service.ts index d8804665da..6e3ef4820a 100644 --- a/server/src/services/storage.service.ts +++ b/server/src/services/storage.service.ts @@ -62,8 +62,8 @@ export class StorageService extends BaseService { }); } - @OnJob({ name: JobName.DeleteFiles, queue: QueueName.BackgroundTask }) - async handleDeleteFiles(job: JobOf): Promise { + @OnJob({ name: JobName.FileDelete, queue: QueueName.BackgroundTask }) + async handleDeleteFiles(job: JobOf): Promise { const { files } = job; // TODO: one job per file diff --git a/server/src/services/trash.service.spec.ts b/server/src/services/trash.service.spec.ts index f742ce8757..e43c49e543 100644 --- a/server/src/services/trash.service.spec.ts +++ b/server/src/services/trash.service.spec.ts @@ -77,24 +77,24 @@ describe(TrashService.name, () => { mocks.trash.empty.mockResolvedValue(1); await expect(sut.empty(authStub.user1)).resolves.toEqual({ count: 1 }); expect(mocks.trash.empty).toHaveBeenCalledWith('user-id'); - expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.QueueTrashEmpty, data: {} }); + expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.AssetEmptyTrash, data: {} }); }); }); describe('onAssetsDelete', () => { it('should queue the empty trash job', async () => { await expect(sut.onAssetsDelete()).resolves.toBeUndefined(); - expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.QueueTrashEmpty, data: {} }); + expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.AssetEmptyTrash, data: {} }); }); }); describe('handleQueueEmptyTrash', () => { it('should queue asset delete jobs', async () => { mocks.trash.getDeletedIds.mockReturnValue(makeAssetIdStream(1)); - await expect(sut.handleQueueEmptyTrash()).resolves.toEqual(JobStatus.Success); + await expect(sut.handleEmptyTrash()).resolves.toEqual(JobStatus.Success); expect(mocks.job.queueAll).toHaveBeenCalledWith([ { - name: JobName.AssetDeletion, + name: JobName.AssetDelete, data: { id: 'asset-1', deleteOnDisk: true }, }, ]); diff --git a/server/src/services/trash.service.ts b/server/src/services/trash.service.ts index 858feacd39..f1d368111e 100644 --- a/server/src/services/trash.service.ts +++ b/server/src/services/trash.service.ts @@ -35,18 +35,18 @@ export class TrashService extends BaseService { async empty(auth: AuthDto): Promise { const count = await this.trashRepository.empty(auth.user.id); if (count > 0) { - await this.jobRepository.queue({ name: JobName.QueueTrashEmpty, data: {} }); + await this.jobRepository.queue({ name: JobName.AssetEmptyTrash, data: {} }); } return { count }; } @OnEvent({ name: 'AssetDeleteAll' }) async onAssetsDelete() { - await this.jobRepository.queue({ name: JobName.QueueTrashEmpty, data: {} }); + await this.jobRepository.queue({ name: JobName.AssetEmptyTrash, data: {} }); } - @OnJob({ name: JobName.QueueTrashEmpty, queue: QueueName.BackgroundTask }) - async handleQueueEmptyTrash() { + @OnJob({ name: JobName.AssetEmptyTrash, queue: QueueName.BackgroundTask }) + async handleEmptyTrash() { const assets = this.trashRepository.getDeletedIds(); let count = 0; @@ -74,7 +74,7 @@ export class TrashService extends BaseService { this.logger.debug(`Queueing ${ids.length} asset(s) for deletion from the trash`); await this.jobRepository.queueAll( ids.map((assetId) => ({ - name: JobName.AssetDeletion, + name: JobName.AssetDelete, data: { id: assetId, deleteOnDisk: true, diff --git a/server/src/services/user-admin.service.spec.ts b/server/src/services/user-admin.service.spec.ts index 8854ade8e3..d8e13fcfbd 100644 --- a/server/src/services/user-admin.service.spec.ts +++ b/server/src/services/user-admin.service.spec.ts @@ -158,7 +158,7 @@ describe(UserAdminService.name, () => { deletedAt: expect.any(Date), }); expect(mocks.job.queue).toHaveBeenCalledWith({ - name: JobName.UserDeletion, + name: JobName.UserDelete, data: { id: userStub.user1.id, force: true }, }); }); diff --git a/server/src/services/user-admin.service.ts b/server/src/services/user-admin.service.ts index 91e21b6bb5..3ae9d429eb 100644 --- a/server/src/services/user-admin.service.ts +++ b/server/src/services/user-admin.service.ts @@ -104,7 +104,7 @@ export class UserAdminService extends BaseService { const user = await this.userRepository.update(id, { status, deletedAt: new Date() }); if (force) { - await this.jobRepository.queue({ name: JobName.UserDeletion, data: { id: user.id, force } }); + await this.jobRepository.queue({ name: JobName.UserDelete, data: { id: user.id, force } }); } return mapUserAdmin(user); diff --git a/server/src/services/user.service.spec.ts b/server/src/services/user.service.spec.ts index 6ae6bc85b6..3a85389ace 100644 --- a/server/src/services/user.service.spec.ts +++ b/server/src/services/user.service.spec.ts @@ -122,7 +122,7 @@ describe(UserService.name, () => { await sut.createProfileImage(authStub.admin, file); - expect(mocks.job.queue.mock.calls).toEqual([[{ name: JobName.DeleteFiles, data: { files } }]]); + expect(mocks.job.queue.mock.calls).toEqual([[{ name: JobName.FileDelete, data: { files } }]]); }); it('should not delete the profile image if it has not been set', async () => { @@ -156,7 +156,7 @@ describe(UserService.name, () => { await sut.deleteProfileImage(authStub.admin); - expect(mocks.job.queue.mock.calls).toEqual([[{ name: JobName.DeleteFiles, data: { files } }]]); + expect(mocks.job.queue.mock.calls).toEqual([[{ name: JobName.FileDelete, data: { files } }]]); }); }); @@ -211,7 +211,7 @@ describe(UserService.name, () => { await sut.handleUserDeleteCheck(); expect(mocks.user.getDeletedAfter).toHaveBeenCalled(); - expect(mocks.job.queueAll).toHaveBeenCalledWith([{ name: JobName.UserDeletion, data: { id: user.id } }]); + expect(mocks.job.queueAll).toHaveBeenCalledWith([{ name: JobName.UserDelete, data: { id: user.id } }]); }); }); diff --git a/server/src/services/user.service.ts b/server/src/services/user.service.ts index 4a65e4ab9f..6849b17ac3 100644 --- a/server/src/services/user.service.ts +++ b/server/src/services/user.service.ts @@ -99,7 +99,7 @@ export class UserService extends BaseService { }); if (oldpath !== '') { - await this.jobRepository.queue({ name: JobName.DeleteFiles, data: { files: [oldpath] } }); + await this.jobRepository.queue({ name: JobName.FileDelete, data: { files: [oldpath] } }); } return { @@ -115,7 +115,7 @@ export class UserService extends BaseService { throw new BadRequestException("Can't delete a missing profile Image"); } await this.userRepository.update(auth.user.id, { profileImagePath: '', profileChangedAt: new Date() }); - await this.jobRepository.queue({ name: JobName.DeleteFiles, data: { files: [user.profileImagePath] } }); + await this.jobRepository.queue({ name: JobName.FileDelete, data: { files: [user.profileImagePath] } }); } async getProfileImage(id: string): Promise { @@ -213,7 +213,7 @@ export class UserService extends BaseService { }; } - @OnJob({ name: JobName.userSyncUsage, queue: QueueName.BackgroundTask }) + @OnJob({ name: JobName.UserSyncUsage, queue: QueueName.BackgroundTask }) async handleUserSyncUsage(): Promise { await this.userRepository.syncUsage(); return JobStatus.Success; @@ -223,12 +223,12 @@ export class UserService extends BaseService { async handleUserDeleteCheck(): Promise { const config = await this.getConfig({ withCache: false }); const users = await this.userRepository.getDeletedAfter(DateTime.now().minus({ days: config.user.deleteDelay })); - await this.jobRepository.queueAll(users.map((user) => ({ name: JobName.UserDeletion, data: { id: user.id } }))); + await this.jobRepository.queueAll(users.map((user) => ({ name: JobName.UserDelete, data: { id: user.id } }))); return JobStatus.Success; } - @OnJob({ name: JobName.UserDeletion, queue: QueueName.BackgroundTask }) - async handleUserDelete({ id, force }: JobOf): Promise { + @OnJob({ name: JobName.UserDelete, queue: QueueName.BackgroundTask }) + async handleUserDelete({ id, force }: JobOf): Promise { const config = await this.getConfig({ withCache: false }); const user = await this.userRepository.get(id, { withDeleted: true }); if (!user) { diff --git a/server/src/services/version.service.ts b/server/src/services/version.service.ts index 5d2f87c2bf..c4d7e9974d 100644 --- a/server/src/services/version.service.ts +++ b/server/src/services/version.service.ts @@ -41,7 +41,7 @@ export class VersionService extends BaseService { const needsNewMemories = semver.lt(previousVersion, '1.129.0'); if (needsNewMemories) { - await this.jobRepository.queue({ name: JobName.MemoriesCreate }); + await this.jobRepository.queue({ name: JobName.MemoryGenerate }); } } }); diff --git a/server/src/types.ts b/server/src/types.ts index 6873613c30..79aeedd47d 100644 --- a/server/src/types.ts +++ b/server/src/types.ts @@ -273,93 +273,93 @@ export interface QueueStatus { export type JobItem = // Backups - | { name: JobName.BackupDatabase; data?: IBaseJob } + | { name: JobName.DatabaseBackup; data?: IBaseJob } // Transcoding - | { name: JobName.QueueVideoConversion; data: IBaseJob } - | { name: JobName.VideoConversation; data: IEntityJob } + | { name: JobName.AssetEncodeVideoQueueAll; data: IBaseJob } + | { name: JobName.AssetEncodeVideo; data: IEntityJob } // Thumbnails - | { name: JobName.QueueGenerateThumbnails; data: IBaseJob } - | { name: JobName.GenerateThumbnails; data: IEntityJob } + | { name: JobName.AssetGenerateThumbnailsQueueAll; data: IBaseJob } + | { name: JobName.AssetGenerateThumbnails; data: IEntityJob } // User | { name: JobName.UserDeleteCheck; data?: IBaseJob } - | { name: JobName.UserDeletion; data: IEntityJob } - | { name: JobName.userSyncUsage; data?: IBaseJob } + | { name: JobName.UserDelete; data: IEntityJob } + | { name: JobName.UserSyncUsage; data?: IBaseJob } // Storage Template | { name: JobName.StorageTemplateMigration; data?: IBaseJob } | { name: JobName.StorageTemplateMigrationSingle; data: IEntityJob } // Migration - | { name: JobName.QueueMigration; data?: IBaseJob } - | { name: JobName.MigrateAsset; data: IEntityJob } - | { name: JobName.MigratePerson; data: IEntityJob } + | { name: JobName.FileMigrationQueueAll; data?: IBaseJob } + | { name: JobName.AssetFileMigration; data: IEntityJob } + | { name: JobName.PersonFileMigration; data: IEntityJob } // Metadata Extraction - | { name: JobName.QueueMetadataExtraction; data: IBaseJob } - | { name: JobName.MetadataExtraction; data: IEntityJob } + | { name: JobName.AssetExtractMetadataQueueAll; data: IBaseJob } + | { name: JobName.AssetExtractMetadata; data: IEntityJob } // Notifications | { name: JobName.NotificationsCleanup; data?: IBaseJob } // Sidecar Scanning - | { name: JobName.QueueSidecar; data: IBaseJob } + | { name: JobName.SidecarQueueAll; data: IBaseJob } | { name: JobName.SidecarDiscovery; data: IEntityJob } | { name: JobName.SidecarSync; data: IEntityJob } | { name: JobName.SidecarWrite; data: ISidecarWriteJob } // Facial Recognition - | { name: JobName.QueueFaceDetection; data: IBaseJob } - | { name: JobName.FaceDetection; data: IEntityJob } - | { name: JobName.QueueFacialRecognition; data: INightlyJob } + | { name: JobName.AssetDetectFacesQueueAll; data: IBaseJob } + | { name: JobName.AssetDetectFaces; data: IEntityJob } + | { name: JobName.FacialRecognitionQueueAll; data: INightlyJob } | { name: JobName.FacialRecognition; data: IDeferrableJob } - | { name: JobName.GeneratePersonThumbnail; data: IEntityJob } + | { name: JobName.PersonGenerateThumbnail; data: IEntityJob } // Smart Search - | { name: JobName.QueueSmartSearch; data: IBaseJob } + | { name: JobName.SmartSearchQueueAll; data: IBaseJob } | { name: JobName.SmartSearch; data: IEntityJob } - | { name: JobName.QueueTrashEmpty; data?: IBaseJob } + | { name: JobName.AssetEmptyTrash; data?: IBaseJob } // Duplicate Detection - | { name: JobName.QueueDuplicateDetection; data: IBaseJob } - | { name: JobName.DuplicateDetection; data: IEntityJob } + | { name: JobName.AssetDetectDuplicatesQueueAll; data: IBaseJob } + | { name: JobName.AssetDetectDuplicates; data: IEntityJob } // Memories - | { name: JobName.MemoriesCleanup; data?: IBaseJob } - | { name: JobName.MemoriesCreate; data?: IBaseJob } + | { name: JobName.MemoryCleanup; data?: IBaseJob } + | { name: JobName.MemoryGenerate; data?: IBaseJob } // Filesystem - | { name: JobName.DeleteFiles; data: IDeleteFilesJob } + | { name: JobName.FileDelete; data: IDeleteFilesJob } // Cleanup - | { name: JobName.CleanOldAuditLogs; data?: IBaseJob } - | { name: JobName.CleanOldSessionTokens; data?: IBaseJob } + | { name: JobName.AuditLogCleanup; data?: IBaseJob } + | { name: JobName.SessionCleanup; data?: IBaseJob } // Tags | { name: JobName.TagCleanup; data?: IBaseJob } // Asset Deletion | { name: JobName.PersonCleanup; data?: IBaseJob } - | { name: JobName.AssetDeletion; data: IAssetDeleteJob } - | { name: JobName.AssetDeletionCheck; data?: IBaseJob } + | { name: JobName.AssetDelete; data: IAssetDeleteJob } + | { name: JobName.AssetDeleteCheck; data?: IBaseJob } // Library Management | { name: JobName.LibrarySyncFiles; data: ILibraryFileJob } - | { name: JobName.LibraryQueueSyncFiles; data: IEntityJob } - | { name: JobName.LibraryQueueSyncAssets; data: IEntityJob } + | { name: JobName.LibrarySyncFilesQueueAll; data: IEntityJob } + | { name: JobName.LibrarySyncAssetsQueueAll; data: IEntityJob } | { name: JobName.LibrarySyncAssets; data: ILibraryBulkIdsJob } - | { name: JobName.LibraryAssetRemoval; data: ILibraryFileJob } + | { name: JobName.LibraryRemoveAsset; data: ILibraryFileJob } | { name: JobName.LibraryDelete; data: IEntityJob } - | { name: JobName.LibraryQueueScanAll; data?: IBaseJob } - | { name: JobName.LibraryQueueCleanup; data: IBaseJob } + | { name: JobName.LibraryScanQueueAll; data?: IBaseJob } + | { name: JobName.LibraryDeleteCheck; data: IBaseJob } // Notification | { name: JobName.SendMail; data: IEmailJob } | { name: JobName.NotifyAlbumInvite; data: INotifyAlbumInviteJob } | { name: JobName.NotifyAlbumUpdate; data: INotifyAlbumUpdateJob } - | { name: JobName.NotifySignup; data: INotifySignupJob } + | { name: JobName.NotifyUserSignup; data: INotifySignupJob } // Version check | { name: JobName.VersionCheck; data: IBaseJob }; diff --git a/server/test/medium/specs/services/user.service.spec.ts b/server/test/medium/specs/services/user.service.spec.ts index f5bddca196..7643be292e 100644 --- a/server/test/medium/specs/services/user.service.spec.ts +++ b/server/test/medium/specs/services/user.service.spec.ts @@ -150,7 +150,7 @@ describe(UserService.name, () => { const { user } = await ctx.newUser({ deletedAt: DateTime.now().minus({ days: 60 }).toJSDate() }); jobMock.queueAll.mockResolvedValue(void 0); await expect(sut.handleUserDeleteCheck()).resolves.toEqual(JobStatus.Success); - expect(jobMock.queueAll).toHaveBeenCalledExactlyOnceWith([{ name: JobName.UserDeletion, data: { id: user.id } }]); + expect(jobMock.queueAll).toHaveBeenCalledExactlyOnceWith([{ name: JobName.UserDelete, data: { id: user.id } }]); }); it('should skip a recently deleted user', async () => { diff --git a/server/test/medium/specs/services/version.service.spec.ts b/server/test/medium/specs/services/version.service.spec.ts index 2d0c57667b..3e81429382 100644 --- a/server/test/medium/specs/services/version.service.spec.ts +++ b/server/test/medium/specs/services/version.service.spec.ts @@ -53,7 +53,7 @@ describe(VersionService.name, () => { await versionHistoryRepo.create({ version: 'v1.128.0' }); await sut.onBootstrap(); - expect(jobMock.queue).toHaveBeenCalledWith({ name: JobName.MemoriesCreate }); + expect(jobMock.queue).toHaveBeenCalledWith({ name: JobName.MemoryGenerate }); }); it('should not queue memory creation when upgrading from 1.129.0', async () => {