fix: locking around concurrency-1 jobs

This commit is contained in:
bo0tzz
2026-05-13 15:18:33 +02:00
parent 6a87797649
commit e2e9dd425f
3 changed files with 188 additions and 177 deletions
+2
View File
@@ -915,6 +915,8 @@ export enum DatabaseLock {
MaintenanceOperation = 621,
MemoryCreation = 777,
VersionCheck = 800,
FacialRecognition = 900,
DuplicateDetection = 1000,
}
export enum MaintenanceAction {
+5 -1
View File
@@ -5,7 +5,7 @@ import { BulkIdErrorReason, BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset
import { MapAsset, mapAsset } from 'src/dtos/asset-response.dto';
import { AuthDto } from 'src/dtos/auth.dto';
import { DuplicateResolveDto, DuplicateResolveGroupDto, DuplicateResponseDto } from 'src/dtos/duplicate.dto';
import { AssetStatus, AssetVisibility, JobName, JobStatus, Permission, QueueName } from 'src/enum';
import { AssetStatus, AssetVisibility, DatabaseLock, JobName, JobStatus, Permission, QueueName } from 'src/enum';
import { AssetDuplicateResult } from 'src/repositories/search.repository';
import { BaseService } from 'src/services/base.service';
import { JobItem, JobOf } from 'src/types';
@@ -300,6 +300,7 @@ export class DuplicateService extends BaseService {
@OnJob({ name: JobName.AssetDetectDuplicatesQueueAll, queue: QueueName.DuplicateDetection })
async handleQueueSearchDuplicates({ force }: JobOf<JobName.AssetDetectDuplicatesQueueAll>): Promise<JobStatus> {
return this.databaseRepository.withLock(DatabaseLock.DuplicateDetection, async () => {
const { machineLearning } = await this.getConfig({ withCache: false });
if (!isDuplicateDetectionEnabled(machineLearning)) {
return JobStatus.Skipped;
@@ -322,10 +323,12 @@ export class DuplicateService extends BaseService {
await queueAll();
return JobStatus.Success;
});
}
@OnJob({ name: JobName.AssetDetectDuplicates, queue: QueueName.DuplicateDetection })
async handleSearchDuplicates({ id }: JobOf<JobName.AssetDetectDuplicates>): Promise<JobStatus> {
return this.databaseRepository.withLock(DatabaseLock.DuplicateDetection, async () => {
const { machineLearning } = await this.getConfig({ withCache: true });
if (!isDuplicateDetectionEnabled(machineLearning)) {
return JobStatus.Skipped;
@@ -380,6 +383,7 @@ export class DuplicateService extends BaseService {
await this.assetRepository.upsertJobStatus(...assetIds.map((assetId) => ({ assetId, duplicatesDetectedAt })));
return JobStatus.Success;
});
}
private async updateDuplicates(
+5
View File
@@ -25,6 +25,7 @@ import {
import {
AssetVisibility,
CacheControl,
DatabaseLock,
JobName,
JobStatus,
Permission,
@@ -402,6 +403,7 @@ export class PersonService extends BaseService {
@OnJob({ name: JobName.FacialRecognitionQueueAll, queue: QueueName.FacialRecognition })
async handleQueueRecognizeFaces({ force, nightly }: JobOf<JobName.FacialRecognitionQueueAll>): Promise<JobStatus> {
return this.databaseRepository.withLock(DatabaseLock.FacialRecognition, async () => {
const { machineLearning } = await this.getConfig({ withCache: false });
if (!isFacialRecognitionEnabled(machineLearning)) {
return JobStatus.Skipped;
@@ -456,10 +458,12 @@ export class PersonService extends BaseService {
await this.systemMetadataRepository.set(SystemMetadataKey.FacialRecognitionState, { lastRun });
return JobStatus.Success;
});
}
@OnJob({ name: JobName.FacialRecognition, queue: QueueName.FacialRecognition })
async handleRecognizeFaces({ id, deferred }: JobOf<JobName.FacialRecognition>): Promise<JobStatus> {
return this.databaseRepository.withLock(DatabaseLock.FacialRecognition, async () => {
const { machineLearning } = await this.getConfig({ withCache: true });
if (!isFacialRecognitionEnabled(machineLearning)) {
return JobStatus.Skipped;
@@ -540,6 +544,7 @@ export class PersonService extends BaseService {
}
return JobStatus.Success;
});
}
@OnJob({ name: JobName.PersonFileMigration, queue: QueueName.Migration })