diff --git a/server/src/main.ts b/server/src/main.ts index 45020fcd37..ecdae3f84f 100644 --- a/server/src/main.ts +++ b/server/src/main.ts @@ -35,7 +35,7 @@ class Workers { if (isMaintenanceMode) { this.startWorker(ImmichWorker.Maintenance); } else { - this.waitForFreeLock(); + await this.waitForFreeLock(); for (const worker of workers) { this.startWorker(worker); diff --git a/server/src/maintenance/maintenance-worker.controller.ts b/server/src/maintenance/maintenance-worker.controller.ts index e57a4e2ac6..40f30eab40 100644 --- a/server/src/maintenance/maintenance-worker.controller.ts +++ b/server/src/maintenance/maintenance-worker.controller.ts @@ -21,7 +21,7 @@ export class MaintenanceWorkerController { constructor(private service: MaintenanceWorkerService) {} @Get('server/config') - getServerConfig(): Promise { + getServerConfig(): ServerConfigDto { return this.service.getSystemConfig(); } diff --git a/server/src/maintenance/maintenance-worker.service.spec.ts b/server/src/maintenance/maintenance-worker.service.spec.ts index 400c08509d..a91ea84cef 100644 --- a/server/src/maintenance/maintenance-worker.service.spec.ts +++ b/server/src/maintenance/maintenance-worker.service.spec.ts @@ -9,6 +9,10 @@ import { MaintenanceWebsocketRepository } from 'src/maintenance/maintenance-webs import { MaintenanceWorkerService } from 'src/maintenance/maintenance-worker.service'; import { automock, AutoMocked, getMocks, mockDuplex, mockSpawn, ServiceMocks } from 'test/utils'; +function* mockData() { + yield ''; +} + describe(MaintenanceWorkerService.name, () => { let sut: MaintenanceWorkerService; let mocks: ServiceMocks; @@ -45,7 +49,7 @@ describe(MaintenanceWorkerService.name, () => { describe('getSystemConfig', () => { it('should respond the server is in maintenance mode', async () => { - await expect(sut.getSystemConfig()).resolves.toMatchObject( + expect(sut.getSystemConfig()).toMatchObject( expect.objectContaining({ maintenanceMode: true, }), @@ -188,10 +192,6 @@ describe(MaintenanceWorkerService.name, () => { describe('action: restore database', () => { beforeEach(() => { - function* mockData() { - yield ''; - } - mocks.database.tryLock.mockResolvedValueOnce(true); mocks.storage.readdir.mockResolvedValue([]); diff --git a/server/src/maintenance/maintenance-worker.service.ts b/server/src/maintenance/maintenance-worker.service.ts index f94fd4a510..6bc74ebae9 100644 --- a/server/src/maintenance/maintenance-worker.service.ts +++ b/server/src/maintenance/maintenance-worker.service.ts @@ -65,7 +65,7 @@ export class MaintenanceWorkerService { /** * {@link _ServerService.getSystemConfig} */ - async getSystemConfig() { + getSystemConfig() { return { maintenanceMode: true, } as ServerConfigDto; @@ -195,12 +195,19 @@ export class MaintenanceWorkerService { async runAction(action: SetMaintenanceModeDto) { switch (action.action) { - case MaintenanceAction.Start: + case MaintenanceAction.Start: { return; - case MaintenanceAction.End: + } + case MaintenanceAction.End: { return this.endMaintenance(); - case MaintenanceAction.RestoreDatabase: - if (!action.restoreBackupFilename) return; + } + case MaintenanceAction.RestoreDatabase: { + if (!action.restoreBackupFilename) { + return; + } + + break; + } } const lock = await this.databaseRepository.tryLock(DatabaseLock.MaintenanceOperation); @@ -220,9 +227,10 @@ export class MaintenanceWorkerService { try { switch (action.action) { - case MaintenanceAction.RestoreDatabase: + case MaintenanceAction.RestoreDatabase: { await this.restoreBackup(action.restoreBackupFilename); break; + } } } catch (error) { this.logger.error(`Encountered error running action: ${error}`); diff --git a/server/src/repositories/process.repository.ts b/server/src/repositories/process.repository.ts index 7ac60326cd..7e0358b786 100644 --- a/server/src/repositories/process.repository.ts +++ b/server/src/repositories/process.repository.ts @@ -94,10 +94,10 @@ export class ProcessRepository { process.on('exit', (code) => { console.info(`${command} exited (${code})`); - if (code !== 0) { - close(new Error(`${command} non-zero exit code (${code})\n${stderr}`)); - } else { + if (code === 0) { close(); + } else { + close(new Error(`${command} non-zero exit code (${code})\n${stderr}`)); } }); diff --git a/server/src/utils/backups.ts b/server/src/utils/backups.ts index 9805359e42..5774c6636d 100644 --- a/server/src/utils/backups.ts +++ b/server/src/utils/backups.ts @@ -230,7 +230,10 @@ export async function restoreBackup( }); const [progressSource, progressSink] = createSqlProgressStreams((progress) => { - if (complete) return; + if (complete) { + return; + } + logger.log(`Restore progress ~ ${(progress * 100).toFixed(2)}%`); progressCb?.('restore', progress); }); diff --git a/server/test/utils.ts b/server/test/utils.ts index 88ca6d1316..8d75752273 100644 --- a/server/test/utils.ts +++ b/server/test/utils.ts @@ -509,11 +509,13 @@ export const mockDuplex = vitest.fn( setImmediate(() => { if (error) { duplex.destroy(error as Error); - } else if (exitCode !== 0) { - duplex.destroy(new Error(`${command} non-zero exit code (${exitCode})\n${stderr}`)); - } else { + } else if (exitCode === 0) { + /* eslint-disable unicorn/prefer-single-call */ duplex.push(stdout); duplex.push(null); + /* eslint-enable unicorn/prefer-single-call */ + } else { + duplex.destroy(new Error(`${command} non-zero exit code (${exitCode})\n${stderr}`)); } });