From aee2227f454aed915044c386e483ba85dfee5345 Mon Sep 17 00:00:00 2001 From: izzy Date: Wed, 5 Nov 2025 12:27:00 +0000 Subject: [PATCH] fix: propagate changes from the CLI to servers --- server/src/commands/maintenance-mode.ts | 4 ++-- server/src/services/cli.service.ts | 25 +++++++++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/server/src/commands/maintenance-mode.ts b/server/src/commands/maintenance-mode.ts index 1b3d3fc2df..1e9c09e163 100644 --- a/server/src/commands/maintenance-mode.ts +++ b/server/src/commands/maintenance-mode.ts @@ -12,7 +12,7 @@ export class EnableMaintenanceModeCommand extends CommandRunner { async run(): Promise { await this.service.enableMaintenanceMode(); - console.log("Maintenance mode has been enabled.\nThis change won't automatically propagate."); + console.log('Maintenance mode has been enabled.'); } } @@ -27,6 +27,6 @@ export class DisableMaintenanceModeCommand extends CommandRunner { async run(): Promise { await this.service.disableMaintenanceMode(); - console.log("Maintenance mode has been disabled.\nThis change won't automatically propagate."); + console.log('Maintenance mode has been disabled.'); } } diff --git a/server/src/services/cli.service.ts b/server/src/services/cli.service.ts index de06b92668..d6be9ee18f 100644 --- a/server/src/services/cli.service.ts +++ b/server/src/services/cli.service.ts @@ -1,12 +1,25 @@ import { Injectable } from '@nestjs/common'; +import { createAdapter } from '@socket.io/redis-adapter'; +import Redis from 'ioredis'; import { isAbsolute } from 'node:path'; +import { Server } from 'socket.io'; import { SALT_ROUNDS } from 'src/constants'; import { UserAdminResponseDto, mapUserAdmin } from 'src/dtos/user.dto'; import { SystemMetadataKey } from 'src/enum'; +import { type ArgsOf } from 'src/repositories/event.repository'; +import { type ServerEvents } from 'src/repositories/websocket.repository'; import { BaseService } from 'src/services/base.service'; @Injectable() export class CliService extends BaseService { + private oneShotServerSend(event: T, ...args: ArgsOf): void { + const server = new Server(); + const pubClient = new Redis(this.configRepository.getEnv().redis); + const subClient = pubClient.duplicate(); + server.adapter(createAdapter(pubClient, subClient)); + server.serverSideEmit(event, ...args); + } + async listUsers(): Promise { const users = await this.userRepository.getList({ withDeleted: true }); return users.map((user) => mapUserAdmin(user)); @@ -39,12 +52,16 @@ export class CliService extends BaseService { await this.updateConfig(config); } - disableMaintenanceMode(): Promise { - return this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, { isMaintenanceMode: false }); + async disableMaintenanceMode(): Promise { + const state = { isMaintenanceMode: false }; + await this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, state); + this.oneShotServerSend('AppRestart', state); } - enableMaintenanceMode(): Promise { - return this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, { isMaintenanceMode: true }); + async enableMaintenanceMode(): Promise { + const state = { isMaintenanceMode: true }; + await this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, state); + this.oneShotServerSend('AppRestart', state); } async grantAdminAccess(email: string): Promise {