diff --git a/redisinsight/api/src/main.ts b/redisinsight/api/src/main.ts index dc215dbbf9..f4db104011 100644 --- a/redisinsight/api/src/main.ts +++ b/redisinsight/api/src/main.ts @@ -7,11 +7,12 @@ import { WinstonModule } from 'nest-winston'; import { GlobalExceptionFilter } from 'src/exceptions/global-exception.filter'; import { get } from 'src/utils'; import { migrateHomeFolder } from 'src/init-helper'; +import { LogFileProvider } from 'src/modules/profiler/providers/log-file.provider'; import { AppModule } from './app.module'; import SWAGGER_CONFIG from '../config/swagger'; import LOGGER_CONFIG from '../config/logger'; -export default async function bootstrap() { +export default async function bootstrap(): Promise { await migrateHomeFolder(); const serverConfig = get('server'); @@ -44,7 +45,7 @@ export default async function bootstrap() { ); } - app.enableShutdownHooks(); + const logFileProvider = app.get(LogFileProvider); await app.listen(port); logger.log({ @@ -52,10 +53,20 @@ export default async function bootstrap() { context: 'bootstrap', }); - process.on('SIGTERM', () => { - logger.log('SIGTERM command received. Shutting down...'); + const gracefulShutdown = (signal) => { + try { + logger.log(`Signal ${signal} received. Shutting down...`); + logFileProvider.onModuleDestroy(); + } catch (e) { + // ignore errors if any + } process.exit(0); - }); + }; + + process.on('SIGTERM', gracefulShutdown); + process.on('SIGINT', gracefulShutdown); + + return gracefulShutdown; } if (process.env.APP_ENV !== 'electron') { diff --git a/redisinsight/api/src/modules/profiler/models/log-file.ts b/redisinsight/api/src/modules/profiler/models/log-file.ts index 3277b35be5..38bd8e4bcd 100644 --- a/redisinsight/api/src/modules/profiler/models/log-file.ts +++ b/redisinsight/api/src/modules/profiler/models/log-file.ts @@ -117,12 +117,12 @@ export class LogFile { /** * Remove file and delete write stream after finish */ - async destroy() { + destroy() { try { this.writeStream?.close(); this.writeStream = null; const size = this.getFileSize(); - await fs.unlink(this.filePath); + fs.unlink(this.filePath); this.analyticsEvents.get(TelemetryEvents.ProfilerLogDeleted)(this.instanceId, size); } catch (e) { diff --git a/redisinsight/api/src/modules/profiler/profiler.module.ts b/redisinsight/api/src/modules/profiler/profiler.module.ts index 88007075da..c42557a135 100644 --- a/redisinsight/api/src/modules/profiler/profiler.module.ts +++ b/redisinsight/api/src/modules/profiler/profiler.module.ts @@ -19,5 +19,6 @@ import { ProfilerService } from './profiler.service'; ProfilerService, ], controllers: [ProfilerController], + exports: [LogFileProvider], }) export class ProfilerModule {} diff --git a/redisinsight/api/src/modules/profiler/providers/log-file.provider.ts b/redisinsight/api/src/modules/profiler/providers/log-file.provider.ts index 1ca2ab1862..953beff549 100644 --- a/redisinsight/api/src/modules/profiler/providers/log-file.provider.ts +++ b/redisinsight/api/src/modules/profiler/providers/log-file.provider.ts @@ -47,7 +47,13 @@ export class LogFileProvider implements OnModuleDestroy { return { stream, filename: logFile.getFilename() }; } - async onModuleDestroy() { - await Promise.all(Array.from(this.profilerLogFiles.values()).map((logFile: LogFile) => logFile.destroy())); + onModuleDestroy() { + this.profilerLogFiles.forEach((logFile) => { + try { + logFile.destroy(); + } catch (e) { + // process other files on error + } + }); } } diff --git a/redisinsight/main.dev.ts b/redisinsight/main.dev.ts index adb920abfb..919676c326 100644 --- a/redisinsight/main.dev.ts +++ b/redisinsight/main.dev.ts @@ -97,12 +97,14 @@ export const getDisplayAppInTrayValue = (): boolean => { * Backend part... */ const port = 5001; + +let backendGracefulShutdown: Function; const launchApiServer = async () => { try { const detectPortConst = await detectPort(port); process.env.API_PORT = detectPortConst?.toString(); log.info('Available port:', detectPortConst); - await server(); + backendGracefulShutdown = await server(); } catch (error) { log.error('Catch server error:', error); } @@ -387,6 +389,13 @@ app.on('certificate-error', (event, _webContents, _url, _error, _certificate, ca callback(true); }); +app.on('quit', () => { + try { + backendGracefulShutdown?.(); + } catch (e) { + // ignore any error + } +}); // ipc events ipcMain.handle(IpcEvent.getAppVersion, () => app?.getVersion());