From 3db28aaa9230dd975ecdc36c1faa427c972a4383 Mon Sep 17 00:00:00 2001 From: Jonathan Jogenfors Date: Thu, 29 Feb 2024 19:02:27 +0100 Subject: [PATCH] fix: ensure lock stays on --- server/src/domain/library/library.service.ts | 8 +++----- .../repositories/database.repository.ts | 2 +- .../infra/repositories/database.repository.ts | 20 +++---------------- .../repositories/database.repository.mock.ts | 1 + 4 files changed, 8 insertions(+), 23 deletions(-) diff --git a/server/src/domain/library/library.service.ts b/server/src/domain/library/library.service.ts index f81d0d3ba6..a1ad99531f 100644 --- a/server/src/domain/library/library.service.ts +++ b/server/src/domain/library/library.service.ts @@ -74,11 +74,9 @@ export class LibraryService extends EventEmitter { const { watch, scan } = config.library; this.watchLibraries = false; if (watch.enabled) { - this.databaseRepository.withTryLock(DatabaseLock.LibraryWatch, async () => { - // This ensures that library watching only occurs in one microservice - // TODO: we could make the lock be per-library instead of global - this.watchLibraries = true; - }); + // This ensures that library watching only occurs in one microservice + // TODO: we could make the lock be per-library instead of global + this.watchLibraries = await this.databaseRepository.tryLock(DatabaseLock.LibraryWatch); } this.jobRepository.addCronJob( 'libraryScan', diff --git a/server/src/domain/repositories/database.repository.ts b/server/src/domain/repositories/database.repository.ts index 0b4317e37c..55911e7ce5 100644 --- a/server/src/domain/repositories/database.repository.ts +++ b/server/src/domain/repositories/database.repository.ts @@ -47,7 +47,7 @@ export interface IDatabaseRepository { shouldReindex(name: VectorIndex): Promise; runMigrations(options?: { transaction?: 'all' | 'none' | 'each' }): Promise; withLock(lock: DatabaseLock, callback: () => Promise): Promise; - withTryLock(lock: DatabaseLock, callback: () => Promise): Promise; + tryLock(lock: DatabaseLock): Promise; isBusy(lock: DatabaseLock): boolean; wait(lock: DatabaseLock): Promise; } diff --git a/server/src/infra/repositories/database.repository.ts b/server/src/infra/repositories/database.repository.ts index d720f24747..66553d38da 100644 --- a/server/src/infra/repositories/database.repository.ts +++ b/server/src/infra/repositories/database.repository.ts @@ -210,23 +210,9 @@ export class DatabaseRepository implements IDatabaseRepository { return res as R; } - async withTryLock(lock: DatabaseLock, callback: () => Promise): Promise { - let res; + async tryLock(lock: DatabaseLock): Promise { const queryRunner = this.dataSource.createQueryRunner(); - try { - const lockAcquired = await this.tryLock(lock, queryRunner); - if (lockAcquired) { - res = await callback(); - } - } finally { - try { - await this.releaseLock(lock, queryRunner); - } finally { - await queryRunner.release(); - } - } - - return res as R; + return await this.acquireTryLock(lock, queryRunner); } isBusy(lock: DatabaseLock): boolean { @@ -241,7 +227,7 @@ export class DatabaseRepository implements IDatabaseRepository { return queryRunner.query('SELECT pg_advisory_lock($1)', [lock]); } - private async tryLock(lock: DatabaseLock, queryRunner: QueryRunner): Promise { + private async acquireTryLock(lock: DatabaseLock, queryRunner: QueryRunner): Promise { return queryRunner.query('SELECT pg_try_advisory_lock($1)', [lock]); } diff --git a/server/test/repositories/database.repository.mock.ts b/server/test/repositories/database.repository.mock.ts index f5a4d39a67..19e2df17a3 100644 --- a/server/test/repositories/database.repository.mock.ts +++ b/server/test/repositories/database.repository.mock.ts @@ -13,6 +13,7 @@ export const newDatabaseRepositoryMock = (): jest.Mocked => shouldReindex: jest.fn(), runMigrations: jest.fn(), withLock: jest.fn().mockImplementation((_, function_: () => Promise) => function_()), + tryLock: jest.fn(), isBusy: jest.fn(), wait: jest.fn(), };