mirror of
https://github.com/immich-app/immich.git
synced 2026-03-07 10:37:22 +03:00
feat(server): conditionally run facial recognition nightly (#11080)
* only run nightly if new person * add tests * use string instead of date * update sql * update tests * simplify condition
This commit is contained in:
@@ -26,6 +26,7 @@ import { AssetFaceEntity } from 'src/entities/asset-face.entity';
|
||||
import { AssetEntity, AssetType } from 'src/entities/asset.entity';
|
||||
import { PersonPathType } from 'src/entities/move.entity';
|
||||
import { PersonEntity } from 'src/entities/person.entity';
|
||||
import { SystemMetadataKey } from 'src/entities/system-metadata.entity';
|
||||
import { IAccessRepository } from 'src/interfaces/access.interface';
|
||||
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.interface';
|
||||
import { ICryptoRepository } from 'src/interfaces/crypto.interface';
|
||||
@@ -34,6 +35,7 @@ import {
|
||||
IDeferrableJob,
|
||||
IEntityJob,
|
||||
IJobRepository,
|
||||
INightlyJob,
|
||||
JOBS_ASSET_PAGINATION_SIZE,
|
||||
JobItem,
|
||||
JobName,
|
||||
@@ -67,7 +69,7 @@ export class PersonService {
|
||||
@Inject(IMoveRepository) moveRepository: IMoveRepository,
|
||||
@Inject(IMediaRepository) private mediaRepository: IMediaRepository,
|
||||
@Inject(IPersonRepository) private repository: IPersonRepository,
|
||||
@Inject(ISystemMetadataRepository) systemMetadataRepository: ISystemMetadataRepository,
|
||||
@Inject(ISystemMetadataRepository) private systemMetadataRepository: ISystemMetadataRepository,
|
||||
@Inject(IStorageRepository) private storageRepository: IStorageRepository,
|
||||
@Inject(IJobRepository) private jobRepository: IJobRepository,
|
||||
@Inject(ISearchRepository) private smartInfoRepository: ISearchRepository,
|
||||
@@ -376,13 +378,26 @@ export class PersonService {
|
||||
return JobStatus.SUCCESS;
|
||||
}
|
||||
|
||||
async handleQueueRecognizeFaces({ force }: IBaseJob): Promise<JobStatus> {
|
||||
async handleQueueRecognizeFaces({ force, nightly }: INightlyJob): Promise<JobStatus> {
|
||||
const { machineLearning } = await this.configCore.getConfig({ withCache: false });
|
||||
if (!isFacialRecognitionEnabled(machineLearning)) {
|
||||
return JobStatus.SKIPPED;
|
||||
}
|
||||
|
||||
await this.jobRepository.waitForQueueCompletion(QueueName.THUMBNAIL_GENERATION, QueueName.FACE_DETECTION);
|
||||
|
||||
if (nightly) {
|
||||
const [state, latestFaceDate] = await Promise.all([
|
||||
this.systemMetadataRepository.get(SystemMetadataKey.FACIAL_RECOGNITION_STATE),
|
||||
this.repository.getLatestFaceDate(),
|
||||
]);
|
||||
|
||||
if (state?.lastRun && latestFaceDate && state.lastRun > latestFaceDate) {
|
||||
this.logger.debug('Skipping facial recognition nightly since no face has been added since the last run');
|
||||
return JobStatus.SKIPPED;
|
||||
}
|
||||
}
|
||||
|
||||
const { waiting } = await this.jobRepository.getJobCounts(QueueName.FACIAL_RECOGNITION);
|
||||
|
||||
if (force) {
|
||||
@@ -394,6 +409,7 @@ export class PersonService {
|
||||
return JobStatus.SKIPPED;
|
||||
}
|
||||
|
||||
const lastRun = new Date().toISOString();
|
||||
const facePagination = usePagination(JOBS_ASSET_PAGINATION_SIZE, (pagination) =>
|
||||
this.repository.getAllFaces(pagination, { where: force ? undefined : { personId: IsNull() } }),
|
||||
);
|
||||
@@ -404,6 +420,8 @@ export class PersonService {
|
||||
);
|
||||
}
|
||||
|
||||
await this.systemMetadataRepository.set(SystemMetadataKey.FACIAL_RECOGNITION_STATE, { lastRun });
|
||||
|
||||
return JobStatus.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user