don't release lock in teardown

This commit is contained in:
Jonathan Jogenfors
2024-02-29 23:54:43 +01:00
parent 38fc1ac0ea
commit 730a58b999
4 changed files with 16 additions and 27 deletions

View File

@@ -42,7 +42,6 @@ describe(LibraryService.name, () => {
let assetMock: jest.Mocked<IAssetRepository>;
let configMock: jest.Mocked<ISystemConfigRepository>;
let cryptoMock: jest.Mocked<ICryptoRepository>;
let userMock: jest.Mocked<IUserRepository>;
let jobMock: jest.Mocked<IJobRepository>;
let libraryMock: jest.Mocked<ILibraryRepository>;
let storageMock: jest.Mocked<IStorageRepository>;
@@ -52,7 +51,6 @@ describe(LibraryService.name, () => {
accessMock = newAccessRepositoryMock();
configMock = newSystemConfigRepositoryMock();
libraryMock = newLibraryRepositoryMock();
userMock = newUserRepositoryMock();
assetMock = newAssetRepositoryMock();
jobMock = newJobRepositoryMock();
cryptoMock = newCryptoRepositoryMock();
@@ -70,7 +68,6 @@ describe(LibraryService.name, () => {
jobMock,
libraryMock,
storageMock,
userMock,
databaseMock,
);
@@ -167,7 +164,6 @@ describe(LibraryService.name, () => {
libraryMock.get.mockResolvedValue(libraryStub.externalLibrary1);
storageMock.crawl.mockResolvedValue(['/data/user1/photo.jpg']);
assetMock.getByLibraryId.mockResolvedValue([]);
userMock.get.mockResolvedValue(userStub.admin);
await sut.handleQueueAssetRefresh(mockLibraryJob);
@@ -194,7 +190,6 @@ describe(LibraryService.name, () => {
libraryMock.get.mockResolvedValue(libraryStub.externalLibrary1);
storageMock.crawl.mockResolvedValue(['/data/user1/photo.jpg']);
assetMock.getByLibraryId.mockResolvedValue([]);
userMock.get.mockResolvedValue(userStub.admin);
await sut.handleQueueAssetRefresh(mockLibraryJob);
@@ -245,7 +240,6 @@ describe(LibraryService.name, () => {
libraryMock.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
storageMock.crawl.mockResolvedValue([]);
assetMock.getByLibraryId.mockResolvedValue([]);
userMock.get.mockResolvedValue(userStub.externalPathRoot);
await sut.handleQueueAssetRefresh(mockLibraryJob);
@@ -261,7 +255,6 @@ describe(LibraryService.name, () => {
beforeEach(() => {
mockUser = userStub.admin;
userMock.get.mockResolvedValue(mockUser);
storageMock.stat.mockResolvedValue({
size: 100,

View File

@@ -57,7 +57,6 @@ export class LibraryService extends EventEmitter {
@Inject(IJobRepository) private jobRepository: IJobRepository,
@Inject(ILibraryRepository) private repository: ILibraryRepository,
@Inject(IStorageRepository) private storageRepository: IStorageRepository,
@Inject(IUserRepository) private userRepository: IUserRepository,
@Inject(IDatabaseRepository) private databaseRepository: IDatabaseRepository,
) {
super();
@@ -97,11 +96,10 @@ export class LibraryService extends EventEmitter {
this.configCore.config$.subscribe(async ({ library }) => {
this.jobRepository.updateCronJob('libraryScan', library.scan.cronExpression, library.scan.enabled);
if (this.watchLock) {
if (library.watch.enabled !== this.watchLibraries) {
this.watchLibraries = library.watch.enabled;
await (this.watchLibraries ? this.watchAll() : this.unwatchAll());
}
if (library.watch.enabled !== this.watchLibraries) {
// Watch configuration changed, update accordingly
this.watchLibraries = library.watch.enabled;
await (this.watchLibraries ? this.watchAll() : this.unwatchAll());
}
});
}
@@ -178,26 +176,30 @@ export class LibraryService extends EventEmitter {
async unwatch(id: string) {
if (this.watchers[id]) {
await this.watchers[id]();
this.watchers[id]();
delete this.watchers[id];
}
}
async teardown() {
await this.unwatchAll();
if (this.watchLock) {
await this.databaseRepository.releaseLock(DatabaseLock.LibraryWatch);
}
}
private async unwatchAll() {
if (!this.watchLock) {
return false;
}
for (const id in this.watchers) {
await this.unwatch(id);
}
}
async watchAll() {
if (!this.watchLock) {
return false;
}
const libraries = await this.repository.getAll(false, LibraryType.EXTERNAL);
for (const library of libraries) {
@@ -278,7 +280,7 @@ export class LibraryService extends EventEmitter {
this.logger.log(`Creating ${dto.type} library for user ${auth.user.name}`);
if (dto.type === LibraryType.EXTERNAL && this.watchLibraries) {
if (dto.type === LibraryType.EXTERNAL) {
await this.watch(library.id);
}

View File

@@ -48,7 +48,6 @@ export interface IDatabaseRepository {
runMigrations(options?: { transaction?: 'all' | 'none' | 'each' }): Promise<void>;
withLock<R>(lock: DatabaseLock, callback: () => Promise<R>): Promise<R>;
tryLock(lock: DatabaseLock): Promise<boolean>;
releaseLock(lock: DatabaseLock): Promise<void>;
isBusy(lock: DatabaseLock): boolean;
wait(lock: DatabaseLock): Promise<void>;
}

View File

@@ -200,7 +200,7 @@ export class DatabaseRepository implements IDatabaseRepository {
res = await callback();
} finally {
try {
await this._releaseLock(lock, queryRunner);
await this.releaseLock(lock, queryRunner);
} finally {
await queryRunner.release();
}
@@ -215,11 +215,6 @@ export class DatabaseRepository implements IDatabaseRepository {
return await this.acquireTryLock(lock, queryRunner);
}
async releaseLock(lock: DatabaseLock): Promise<void> {
const queryRunner = this.dataSource.createQueryRunner();
return await this._releaseLock(lock, queryRunner);
}
isBusy(lock: DatabaseLock): boolean {
return this.asyncLock.isBusy(DatabaseLock[lock]);
}
@@ -237,7 +232,7 @@ export class DatabaseRepository implements IDatabaseRepository {
return lockResult[0].pg_try_advisory_lock;
}
private async _releaseLock(lock: DatabaseLock, queryRunner: QueryRunner): Promise<void> {
private async releaseLock(lock: DatabaseLock, queryRunner: QueryRunner): Promise<void> {
return queryRunner.query('SELECT pg_advisory_unlock($1)', [lock]);
}
}