Przeglądaj źródła

imprv: Apply terminus for graceful shutdown (#4398)

* add latest terminus

* improve SocketIoService

* apply terminus

* set signals SIGINT and SIGTERM
Yuki Takei 4 lat temu
rodzic
commit
091080c3dd

+ 1 - 0
packages/app/package.json

@@ -53,6 +53,7 @@
   },
   },
   "dependencies": {
   "dependencies": {
     "@browser-bunyan/console-formatted-stream": "^1.6.2",
     "@browser-bunyan/console-formatted-stream": "^1.6.2",
+    "@godaddy/terminus": "^4.9.0",
     "@google-cloud/storage": "^5.8.5",
     "@google-cloud/storage": "^5.8.5",
     "@growi/codemirror-textlint": "^4.4.7-RC.0",
     "@growi/codemirror-textlint": "^4.4.7-RC.0",
     "@growi/plugin-attachment-refs": "^4.4.7-RC.0",
     "@growi/plugin-attachment-refs": "^4.4.7-RC.0",

+ 27 - 4
packages/app/src/server/crowi/index.js

@@ -1,8 +1,11 @@
 /* eslint-disable @typescript-eslint/no-this-alias */
 /* eslint-disable @typescript-eslint/no-this-alias */
 
 
 import path from 'path';
 import path from 'path';
+import http from 'http';
 import mongoose from 'mongoose';
 import mongoose from 'mongoose';
 
 
+import { createTerminus } from '@godaddy/terminus';
+
 import { initMongooseGlobalSettings, getMongoUri, mongoOptions } from '@growi/core';
 import { initMongooseGlobalSettings, getMongoUri, mongoOptions } from '@growi/core';
 import pkg from '^/package.json';
 import pkg from '^/package.json';
 
 
@@ -409,10 +412,17 @@ Crowi.prototype.start = async function() {
   this.pluginService = new PluginService(this, express);
   this.pluginService = new PluginService(this, express);
   await this.pluginService.autoDetectAndLoadPlugins();
   await this.pluginService.autoDetectAndLoadPlugins();
 
 
-  const server = (this.node_env === 'development') ? this.crowiDev.setupServer(express) : express;
+  const app = (this.node_env === 'development') ? this.crowiDev.setupServer(express) : express;
+
+  const httpServer = http.createServer(app);
+
+  // setup terminus
+  this.setupTerminus(httpServer);
+  // attach to socket.io
+  this.socketIoService.attachServer(httpServer);
 
 
   // listen
   // listen
-  const serverListening = server.listen(this.port, () => {
+  const serverListening = httpServer.listen(this.port, () => {
     logger.info(`[${this.node_env}] Express server is listening on port ${this.port}`);
     logger.info(`[${this.node_env}] Express server is listening on port ${this.port}`);
     if (this.node_env === 'development') {
     if (this.node_env === 'development') {
       this.crowiDev.setupExpressAfterListening(express);
       this.crowiDev.setupExpressAfterListening(express);
@@ -428,8 +438,6 @@ Crowi.prototype.start = async function() {
     });
     });
   }
   }
 
 
-  this.socketIoService.attachServer(serverListening);
-
   // setup Express Routes
   // setup Express Routes
   this.setupRoutesAtLast();
   this.setupRoutesAtLast();
 
 
@@ -463,6 +471,21 @@ Crowi.prototype.buildServer = async function() {
   this.express = express;
   this.express = express;
 };
 };
 
 
+Crowi.prototype.setupTerminus = function(server) {
+  createTerminus(server, {
+    signals: ['SIGINT', 'SIGTERM'],
+    onSignal: async() => {
+      logger.info('Server is starting cleanup');
+
+      await mongoose.disconnect();
+      return;
+    },
+    onShutdown: async() => {
+      logger.info('Cleanup finished, server is shutting down');
+    },
+  });
+};
+
 /**
 /**
  * setup Express Routes
  * setup Express Routes
  * !! this must be at last because it includes '/*' route !!
  * !! this must be at last because it includes '/*' route !!

+ 5 - 2
packages/app/src/server/service/socket-io.js

@@ -1,7 +1,8 @@
+import { Server } from 'socket.io';
+
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 import { RoomPrefix, getRoomNameWithId } from '../util/socket-io-helpers';
 import { RoomPrefix, getRoomNameWithId } from '../util/socket-io-helpers';
 
 
-const socketIo = require('socket.io');
 const expressSession = require('express-session');
 const expressSession = require('express-session');
 const passport = require('passport');
 const passport = require('passport');
 
 
@@ -26,9 +27,11 @@ class SocketIoService {
 
 
   // Since the Order is important, attachServer() should be async
   // Since the Order is important, attachServer() should be async
   async attachServer(server) {
   async attachServer(server) {
-    this.io = socketIo(server, {
+    this.io = new Server({
       transports: ['websocket'],
       transports: ['websocket'],
+      serveClient: false,
     });
     });
+    this.io.attach(server);
 
 
     // create namespace for admin
     // create namespace for admin
     this.adminNamespace = this.io.of('/admin');
     this.adminNamespace = this.io.of('/admin');

+ 1 - 1
packages/slackbot-proxy/package.json

@@ -24,7 +24,7 @@
     "read-pkg-up": "v8 doesn't support CommonJS anymore. https://github.com/sindresorhus/read-pkg-up/issues/17"
     "read-pkg-up": "v8 doesn't support CommonJS anymore. https://github.com/sindresorhus/read-pkg-up/issues/17"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@godaddy/terminus": "^4.8.0",
+    "@godaddy/terminus": "^4.9.0",
     "@growi/slack": "^4.4.7-RC.0",
     "@growi/slack": "^4.4.7-RC.0",
     "@slack/oauth": "^2.0.1",
     "@slack/oauth": "^2.0.1",
     "@slack/web-api": "^6.2.4",
     "@slack/web-api": "^6.2.4",

+ 4 - 4
yarn.lock

@@ -1093,10 +1093,10 @@
     minimatch "^3.0.4"
     minimatch "^3.0.4"
     strip-json-comments "^3.1.1"
     strip-json-comments "^3.1.1"
 
 
-"@godaddy/terminus@^4.8.0":
-  version "4.8.0"
-  resolved "https://registry.yarnpkg.com/@godaddy/terminus/-/terminus-4.8.0.tgz#7f1258abd731adcf5f08d8ff1aa0216a02d65062"
-  integrity sha512-C3u+LTmlhtqsk1Sjw9UDTAXfVngby62dJL71LyhpRcwX3FDeLb0yd1Rmxh1OjH5HouOr0IIuU4dhiJMT6NNXog==
+"@godaddy/terminus@^4.9.0":
+  version "4.9.0"
+  resolved "https://registry.yarnpkg.com/@godaddy/terminus/-/terminus-4.9.0.tgz#c7de0b45ede05116854d1461832dd05df169f689"
+  integrity sha512-j1E22ZK5jW+DVb2vIEOx9I6epWT/geJyWzuxsUThyPcds5UxjCBeKcDTtNVkoWLRASM49o9OKRrCKKybX7z9bw==
   dependencies:
   dependencies:
     stoppable "^1.1.0"
     stoppable "^1.1.0"