diff --git a/Dockerfile b/Dockerfile index 45ca57bc2..787e248cb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -86,4 +86,4 @@ ENV MALLOC_CONF=background_thread:true,metadata_thp:auto,dirty_decay_ms:30000,mu ENV NODE_ENV=production HEALTHCHECK --interval=5s --retries=20 CMD ["/bin/bash", "/misskey/healthcheck.sh"] ENTRYPOINT ["/usr/bin/tini", "--"] -CMD ["pnpm", "run", "migrateandstart"] +CMD ["pnpm", "run", "migrateandstart:docker"] diff --git a/package.json b/package.json index b385fcaea..e531e1a76 100644 --- a/package.json +++ b/package.json @@ -18,11 +18,13 @@ "build": "pnpm build-pre && pnpm -r build && pnpm gulp", "build-storybook": "pnpm --filter frontend build-storybook", "start": "pnpm check:connect && cd packages/backend && node ./built/boot/index.js", + "start:docker": "pnpm check:connect && cd packages/backend && exec node ./built/boot/index.js", "start:test": "cd packages/backend && cross-env NODE_ENV=test node ./built/boot/index.js", "init": "pnpm migrate", "migrate": "cd packages/backend && pnpm migrate", "check:connect": "cd packages/backend && pnpm check:connect", "migrateandstart": "pnpm migrate && pnpm start", + "migrateandstart:docker": "pnpm migrate && exec pnpm start:docker", "gulp": "pnpm exec gulp build", "watch": "pnpm dev", "dev": "node ./scripts/dev.mjs", diff --git a/packages/backend/src/boot/index.ts b/packages/backend/src/boot/index.ts index fc8fc2ffb..2b1f609e9 100644 --- a/packages/backend/src/boot/index.ts +++ b/packages/backend/src/boot/index.ts @@ -29,23 +29,39 @@ const ev = new Xev(); //#region Events -// Listen new workers -cluster.on('fork', worker => { - clusterLogger.debug(`Process forked: [${worker.id}]`); -}); +if (cluster.isPrimary && !envOption.disableClustering) { + // Listen new workers + cluster.on('fork', worker => { + clusterLogger.debug(`Process forked: [${worker.id}]`); + }); -// Listen online workers -cluster.on('online', worker => { - clusterLogger.debug(`Process is now online: [${worker.id}]`); -}); + // Listen online workers + cluster.on('online', worker => { + clusterLogger.debug(`Process is now online: [${worker.id}]`); + }); -// Listen for dying workers -cluster.on('exit', worker => { - // Replace the dead worker, - // we're not sentimental - clusterLogger.error(chalk.red(`[${worker.id}] died :(`)); - cluster.fork(); -}); + // Listen for dying workers + cluster.on('exit', (worker, code, signal?) => { + // Replace the dead worker, + // we're not sentimental + if (signal) { + switch (signal) { + case 'SIGINT': + case 'SIGTERM': + console.log(chalk.green(`[${worker.id}] exited by signal: ${signal}`)); + break; + default: + console.error(chalk.red(`[${worker.id}] killed by signal: ${signal}`)); + cluster.fork(); + break; + } + } else if (code !== 0) { + console.error(chalk.red(`[${worker.id}] exited with error code: ${code}`)); + } else { + console.log(chalk.green(`[${worker.id}] exited normally`)); + } + }); +} // Display detail of unhandled promise rejection if (!envOption.quiet) { diff --git a/packages/backend/src/server/ServerService.ts b/packages/backend/src/server/ServerService.ts index 4a61ed521..5719189c6 100644 --- a/packages/backend/src/server/ServerService.ts +++ b/packages/backend/src/server/ServerService.ts @@ -254,7 +254,7 @@ export class ServerService implements OnApplicationShutdown { @bindThis public async dispose(): Promise { - await this.streamingApiServerService.detach(); + this.streamingApiServerService.detach(); await this.#fastify.close(); } diff --git a/packages/backend/src/server/api/StreamingApiServerService.ts b/packages/backend/src/server/api/StreamingApiServerService.ts index afa0bc582..b8022dd76 100644 --- a/packages/backend/src/server/api/StreamingApiServerService.ts +++ b/packages/backend/src/server/api/StreamingApiServerService.ts @@ -173,13 +173,12 @@ export class StreamingApiServerService { } @bindThis - public detach(): Promise { + public detach(): void { if (this.#cleanConnectionsIntervalId) { clearInterval(this.#cleanConnectionsIntervalId); this.#cleanConnectionsIntervalId = null; } - return new Promise((resolve) => { - this.#wss.close(() => resolve()); - }); + this.#wss.close(); + this.#wss.clients.forEach(client => client.terminate()); } }