mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:27:09 -05:00 
			
		
		
		
	feat: add job ids
This commit is contained in:
		
							parent
							
								
									c5360e78c5
								
							
						
					
					
						commit
						00ec2bd525
					
				@ -144,7 +144,6 @@ export interface IAssetDeleteJob extends IEntityJob {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ILibraryFileJob extends IEntityJob {
 | 
			
		||||
  ownerId: string;
 | 
			
		||||
  assetPath: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -216,6 +216,17 @@ export class JobRepository implements IJobRepository {
 | 
			
		||||
 | 
			
		||||
  private getJobOptions(item: JobItem): JobsOptions | null {
 | 
			
		||||
    switch (item.name) {
 | 
			
		||||
      case JobName.LIBRARY_QUEUE_SYNC_ASSETS:
 | 
			
		||||
      case JobName.LIBRARY_QUEUE_SYNC_FILES:
 | 
			
		||||
      case JobName.LIBRARY_SYNC_ASSET:
 | 
			
		||||
      case JobName.LIBRARY_DELETE:
 | 
			
		||||
      case JobName.SIDECAR_SYNC:
 | 
			
		||||
      case JobName.SIDECAR_DISCOVERY: {
 | 
			
		||||
        return { jobId: `${item.data.id}-${item.name}` };
 | 
			
		||||
      }
 | 
			
		||||
      case JobName.LIBRARY_SYNC_FILE: {
 | 
			
		||||
        return { jobId: `${item.data.id}-${item.data.assetPath}` };
 | 
			
		||||
      }
 | 
			
		||||
      case JobName.NOTIFY_ALBUM_UPDATE: {
 | 
			
		||||
        return { jobId: item.data.id, delay: item.data?.delay };
 | 
			
		||||
      }
 | 
			
		||||
@ -228,6 +239,11 @@ export class JobRepository implements IJobRepository {
 | 
			
		||||
      case JobName.QUEUE_FACIAL_RECOGNITION: {
 | 
			
		||||
        return { jobId: JobName.QUEUE_FACIAL_RECOGNITION };
 | 
			
		||||
      }
 | 
			
		||||
      case JobName.LIBRARY_QUEUE_SYNC_ALL:
 | 
			
		||||
      case JobName.LIBRARY_QUEUE_CLEANUP: {
 | 
			
		||||
        // These jobs are globally unique and should only have one instance running at a time
 | 
			
		||||
        return { jobId: item.name };
 | 
			
		||||
      }
 | 
			
		||||
      default: {
 | 
			
		||||
        return null;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -181,7 +181,6 @@ describe(LibraryService.name, () => {
 | 
			
		||||
          name: JobName.LIBRARY_SYNC_FILE,
 | 
			
		||||
          data: {
 | 
			
		||||
            id: libraryStub.externalLibrary1.id,
 | 
			
		||||
            ownerId: libraryStub.externalLibrary1.owner.id,
 | 
			
		||||
            assetPath: '/data/user1/photo.jpg',
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
@ -401,7 +400,6 @@ describe(LibraryService.name, () => {
 | 
			
		||||
    it('should import a new asset', async () => {
 | 
			
		||||
      const mockLibraryJob: ILibraryFileJob = {
 | 
			
		||||
        id: libraryStub.externalLibrary1.id,
 | 
			
		||||
        ownerId: mockUser.id,
 | 
			
		||||
        assetPath: '/data/user1/photo.jpg',
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@ -445,7 +443,6 @@ describe(LibraryService.name, () => {
 | 
			
		||||
    it('should import a new video', async () => {
 | 
			
		||||
      const mockLibraryJob: ILibraryFileJob = {
 | 
			
		||||
        id: libraryStub.externalLibrary1.id,
 | 
			
		||||
        ownerId: mockUser.id,
 | 
			
		||||
        assetPath: '/data/user1/video.mp4',
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@ -489,7 +486,6 @@ describe(LibraryService.name, () => {
 | 
			
		||||
    it('should not import an asset to a soft deleted library', async () => {
 | 
			
		||||
      const mockLibraryJob: ILibraryFileJob = {
 | 
			
		||||
        id: libraryStub.externalLibrary1.id,
 | 
			
		||||
        ownerId: mockUser.id,
 | 
			
		||||
        assetPath: '/data/user1/photo.jpg',
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@ -504,7 +500,6 @@ describe(LibraryService.name, () => {
 | 
			
		||||
    it('should not refresh a file whose mtime matches existing asset', async () => {
 | 
			
		||||
      const mockLibraryJob: ILibraryFileJob = {
 | 
			
		||||
        id: libraryStub.externalLibrary1.id,
 | 
			
		||||
        ownerId: mockUser.id,
 | 
			
		||||
        assetPath: assetStub.hasFileExtension.originalPath,
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@ -522,10 +517,9 @@ describe(LibraryService.name, () => {
 | 
			
		||||
      expect(jobMock.queueAll).not.toHaveBeenCalled();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('should skip existing asset', async () => {
 | 
			
		||||
    it('should skip an existing asset', async () => {
 | 
			
		||||
      const mockLibraryJob: ILibraryFileJob = {
 | 
			
		||||
        id: libraryStub.externalLibrary1.id,
 | 
			
		||||
        ownerId: mockUser.id,
 | 
			
		||||
        assetPath: '/data/user1/photo.jpg',
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@ -537,7 +531,6 @@ describe(LibraryService.name, () => {
 | 
			
		||||
    it('should not refresh an asset trashed by user', async () => {
 | 
			
		||||
      const mockLibraryJob: ILibraryFileJob = {
 | 
			
		||||
        id: libraryStub.externalLibrary1.id,
 | 
			
		||||
        ownerId: mockUser.id,
 | 
			
		||||
        assetPath: assetStub.hasFileExtension.originalPath,
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@ -554,7 +547,6 @@ describe(LibraryService.name, () => {
 | 
			
		||||
 | 
			
		||||
      const mockLibraryJob: ILibraryFileJob = {
 | 
			
		||||
        id: libraryStub.externalLibrary1.id,
 | 
			
		||||
        ownerId: userStub.admin.id,
 | 
			
		||||
        assetPath: '/data/user1/photo.jpg',
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@ -572,7 +564,6 @@ describe(LibraryService.name, () => {
 | 
			
		||||
 | 
			
		||||
      const mockLibraryJob: ILibraryFileJob = {
 | 
			
		||||
        id: libraryStub.externalLibrary1.id,
 | 
			
		||||
        ownerId: userStub.admin.id,
 | 
			
		||||
        assetPath: '/data/user1/photo.jpg',
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@ -923,7 +914,6 @@ describe(LibraryService.name, () => {
 | 
			
		||||
            data: {
 | 
			
		||||
              id: libraryStub.externalLibraryWithImportPaths1.id,
 | 
			
		||||
              assetPath: '/foo/photo.jpg',
 | 
			
		||||
              ownerId: libraryStub.externalLibraryWithImportPaths1.owner.id,
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        ]);
 | 
			
		||||
@ -948,7 +938,6 @@ describe(LibraryService.name, () => {
 | 
			
		||||
            data: {
 | 
			
		||||
              id: libraryStub.externalLibraryWithImportPaths1.id,
 | 
			
		||||
              assetPath: '/foo/photo.jpg',
 | 
			
		||||
              ownerId: libraryStub.externalLibraryWithImportPaths1.owner.id,
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
@ -228,14 +228,13 @@ export class LibraryService extends BaseService {
 | 
			
		||||
    return mapLibrary(library);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async syncFiles({ id, ownerId }: LibraryEntity, assetPaths: string[]) {
 | 
			
		||||
  private async syncFiles({ id }: LibraryEntity, assetPaths: string[]) {
 | 
			
		||||
    await this.jobRepository.queueAll(
 | 
			
		||||
      assetPaths.map((assetPath) => ({
 | 
			
		||||
        name: JobName.LIBRARY_SYNC_FILE,
 | 
			
		||||
        data: {
 | 
			
		||||
          id,
 | 
			
		||||
          assetPath,
 | 
			
		||||
          ownerId,
 | 
			
		||||
        },
 | 
			
		||||
      })),
 | 
			
		||||
    );
 | 
			
		||||
@ -401,7 +400,7 @@ export class LibraryService extends BaseService {
 | 
			
		||||
    const mtime = stat.mtime;
 | 
			
		||||
 | 
			
		||||
    asset = await this.assetRepository.create({
 | 
			
		||||
      ownerId: job.ownerId,
 | 
			
		||||
      ownerId: library.ownerId,
 | 
			
		||||
      libraryId: job.id,
 | 
			
		||||
      checksum: pathHash,
 | 
			
		||||
      originalPath: assetPath,
 | 
			
		||||
@ -433,12 +432,18 @@ export class LibraryService extends BaseService {
 | 
			
		||||
  async queueScan(id: string) {
 | 
			
		||||
    await this.findOrFail(id);
 | 
			
		||||
 | 
			
		||||
    // We purge any existing scan jobs for this library. This is because the scan settings
 | 
			
		||||
    // might have changed and the user wants to start a new scan with these settings.
 | 
			
		||||
    await this.jobRepository.removeJob(id, JobName.LIBRARY_QUEUE_SYNC_FILES);
 | 
			
		||||
    await this.jobRepository.removeJob(id, JobName.LIBRARY_QUEUE_SYNC_ASSETS);
 | 
			
		||||
 | 
			
		||||
    await this.jobRepository.queue({
 | 
			
		||||
      name: JobName.LIBRARY_QUEUE_SYNC_FILES,
 | 
			
		||||
      data: {
 | 
			
		||||
        id,
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    await this.jobRepository.queue({ name: JobName.LIBRARY_QUEUE_SYNC_ASSETS, data: { id } });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user