mirror of
https://github.com/immich-app/immich
synced 2026-08-22 13:13:05 +00:00
refactor: move maintenance resolution code to static method in service
This commit is contained in:
parent
018af805e6
commit
58c4a41eed
3 changed files with 37 additions and 25 deletions
|
|
@ -3,11 +3,11 @@ import { CommandFactory } from 'nest-commander';
|
|||
import { ChildProcess, fork } from 'node:child_process';
|
||||
import { dirname, join } from 'node:path';
|
||||
import { Worker } from 'node:worker_threads';
|
||||
import { PostgresError } from 'postgres';
|
||||
import { ApiModule, ImmichAdminModule } from 'src/app.module';
|
||||
import { ImmichWorker, LogLevel, SystemMetadataKey } from 'src/enum';
|
||||
import { ImmichWorker, LogLevel } from 'src/enum';
|
||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
||||
import { MaintenanceService } from 'src/services/maintenance.service';
|
||||
|
||||
/**
|
||||
* Manages worker lifecycle
|
||||
|
|
@ -47,22 +47,13 @@ class Workers {
|
|||
* Initialise a short-lived Nest application to build configuration
|
||||
* @returns System configuration
|
||||
*/
|
||||
private async getConfig(): Promise<{ isMaintenanceMode?: boolean }> {
|
||||
try {
|
||||
const app = await NestFactory.create(ApiModule);
|
||||
const metadataRepo = app.get(SystemMetadataRepository);
|
||||
private async getConfig(): Promise<{ isMaintenanceMode: boolean }> {
|
||||
const app = await NestFactory.create(ApiModule);
|
||||
const metadataRepository = app.get(SystemMetadataRepository);
|
||||
|
||||
await app.close();
|
||||
await app.close();
|
||||
|
||||
return metadataRepo.get(SystemMetadataKey.MaintenanceMode).then((value) => value ?? {});
|
||||
} catch (err) {
|
||||
// Table doesn't exist (migrations haven't run yet)
|
||||
if (err instanceof PostgresError && err.code === '42P01') {
|
||||
return { isMaintenanceMode: false };
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
return await MaintenanceService.getMaintenanceModeWith(metadataRepository);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,16 +1,33 @@
|
|||
import { BadRequestException, INestApplication, Injectable } from '@nestjs/common';
|
||||
import { PostgresError } from 'postgres';
|
||||
import { OnEvent } from 'src/decorators';
|
||||
import { MaintenanceModeResponseDto } from 'src/dtos/maintenance.dto';
|
||||
import { SystemMetadataKey } from 'src/enum';
|
||||
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
||||
import { BaseService } from 'src/services/base.service';
|
||||
|
||||
@Injectable()
|
||||
export class MaintenanceService extends BaseService {
|
||||
nestApplication: INestApplication | undefined;
|
||||
|
||||
async getMaintenanceMode(): Promise<MaintenanceModeResponseDto> {
|
||||
const value = await this.systemMetadataRepository.get(SystemMetadataKey.MaintenanceMode);
|
||||
return { isMaintenanceMode: false, ...value };
|
||||
static getMaintenanceModeWith(
|
||||
systemMetadataRepository: SystemMetadataRepository,
|
||||
): Promise<{ isMaintenanceMode: boolean }> {
|
||||
return systemMetadataRepository
|
||||
.get(SystemMetadataKey.MaintenanceMode)
|
||||
.catch((err) => {
|
||||
// Table doesn't exist (migrations haven't run yet)
|
||||
if (err instanceof PostgresError && err.code === '42P01') {
|
||||
return { isMaintenanceMode: false };
|
||||
}
|
||||
|
||||
throw err;
|
||||
})
|
||||
.then((value) => ({ ...value, isMaintenanceMode: false }));
|
||||
}
|
||||
|
||||
getMaintenanceMode(): Promise<MaintenanceModeResponseDto> {
|
||||
return MaintenanceService.getMaintenanceModeWith(this.systemMetadataRepository);
|
||||
}
|
||||
|
||||
private async setMaintenanceMode(isMaintenanceMode: boolean) {
|
||||
|
|
@ -18,7 +35,7 @@ export class MaintenanceService extends BaseService {
|
|||
await this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, state);
|
||||
this.websocketRepository.clientBroadcast('on_server_restart', state);
|
||||
this.websocketRepository.serverSend('AppRestart');
|
||||
this.eventRepository.emit('AppRestart');
|
||||
await this.eventRepository.emit('AppRestart');
|
||||
}
|
||||
|
||||
async startMaintenance(): Promise<void> {
|
||||
|
|
@ -27,7 +44,7 @@ export class MaintenanceService extends BaseService {
|
|||
throw new BadRequestException('Already in maintenance mode');
|
||||
}
|
||||
|
||||
this.setMaintenanceMode(true);
|
||||
await this.setMaintenanceMode(true);
|
||||
}
|
||||
|
||||
async endMaintenance(): Promise<void> {
|
||||
|
|
@ -36,16 +53,19 @@ export class MaintenanceService extends BaseService {
|
|||
throw new BadRequestException('Not in maintenance mode');
|
||||
}
|
||||
|
||||
this.setMaintenanceMode(false);
|
||||
await this.setMaintenanceMode(false);
|
||||
}
|
||||
|
||||
@OnEvent({ name: 'AppRestart', server: true })
|
||||
onRestart() {
|
||||
this.nestApplication
|
||||
/* eslint-disable unicorn/no-process-exit */
|
||||
// we need to specify the exact exit code
|
||||
void this.nestApplication
|
||||
?.close() // attempt graceful shutdown
|
||||
.then(() => process.exit(7)); // then signal restart
|
||||
|
||||
// in some exceptional circumstances, close() may hang
|
||||
setTimeout(() => process.exit(7), 5000);
|
||||
/* eslint-enable unicorn/no-process-exit */
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import {
|
|||
import { StorageFolder, SystemMetadataKey } from 'src/enum';
|
||||
import { UserStatsQueryResponse } from 'src/repositories/user.repository';
|
||||
import { BaseService } from 'src/services/base.service';
|
||||
import { MaintenanceService } from 'src/services/maintenance.service';
|
||||
import { asHumanReadable } from 'src/utils/bytes';
|
||||
import { mimeTypes } from 'src/utils/mime-types';
|
||||
import {
|
||||
|
|
@ -118,7 +119,7 @@ export class ServerService extends BaseService {
|
|||
const config = await this.getConfig({ withCache: false });
|
||||
const isInitialized = await this.userRepository.hasAdmin();
|
||||
const onboarding = await this.systemMetadataRepository.get(SystemMetadataKey.AdminOnboarding);
|
||||
const maintenanceMode = await this.systemMetadataRepository.get(SystemMetadataKey.MaintenanceMode);
|
||||
const { isMaintenanceMode } = await MaintenanceService.getMaintenanceModeWith(this.systemMetadataRepository);
|
||||
|
||||
return {
|
||||
loginPageMessage: config.server.loginPageMessage,
|
||||
|
|
@ -131,7 +132,7 @@ export class ServerService extends BaseService {
|
|||
publicUsers: config.server.publicUsers,
|
||||
mapDarkStyleUrl: config.map.darkStyle,
|
||||
mapLightStyleUrl: config.map.lightStyle,
|
||||
maintenanceMode: maintenanceMode?.isMaintenanceMode || false,
|
||||
maintenanceMode: isMaintenanceMode,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue