Allow to gracefully stop the server
authorRaphaël Jakse <raphael.jakse@univ-grenoble-alpes.fr>
Sun, 5 Apr 2020 10:51:47 +0000 (12:51 +0200)
committerRaphaël Jakse <raphael.jakse@univ-grenoble-alpes.fr>
Sun, 5 Apr 2020 10:51:47 +0000 (12:51 +0200)
trivabble-server.js

index 5765d86947b16afc794733f62eba0d1514b02c73..b3c88f1eaf55ee4041317f610f482eb0265292db 100644 (file)
@@ -112,11 +112,19 @@ var games = {};
 var dateNow = 0;
 
 var saveTimeout = null;
+var running = true;
 
-function saveGames() {
+function saveGames(exit) {
     fs.writeFile("games.backup.json", JSON.stringify(games), function (err) {
         if (err) {
             console.error("ERROR: Cannot save games!");
+        } else if (exit) {
+            console.log("Games saved.");
+        }
+
+        if (exit) {
+            // eslint-disable-next-line no-process-exit
+            process.exit(0);
         }
     });
 
@@ -137,11 +145,31 @@ function writeResponse(responseAndIsES, data, terminate) {
             : data.length + data
     );
 
-    if (!terminate) {
+    if (terminate) {
+        stopKeepAlive(responseAndIsES);
+    } else {
         keepAlive(responseAndIsES);
     }
 }
 
+function stop() {
+    running = false;
+    console.log("Closing connections and saving the game state...");
+
+    let listeningPlayerCount = 0;
+
+    for (const gameID of Object.keys(games)) {
+        const game = games[gameID];
+        for (const listeningPlayer of game.listeningPlayers) {
+            writeResponse(listeningPlayer, '{"stopping": 2000}', true);
+        }
+        listeningPlayerCount += game.listeningPlayers.length;
+    }
+
+    console.log("Stopped", games.length, "games and ", listeningPlayerCount, " player connections.");
+    saveGames(true);
+}
+
 function stopKeepAlive(responseAndIsES) {
     if (responseAndIsES.keepAliveTimeout) {
         clearTimeout(responseAndIsES.keepAliveTimeout);
@@ -714,6 +742,13 @@ function handleRequest(request, response) {
     });
 
     request.on("end", function () {
+        if (!running) {
+            response.statusCode = 503;
+            response.statusMessage = "Server is stopping";
+            response.end("Server is stopping");
+            return;
+        }
+
         if (DEV_ENABLE_SERVING_FILES && !request.url.startsWith("/:")) {
             if (request.url === "/") {
                 request.url = "/index.html";
@@ -797,3 +832,14 @@ fs.readFile("games.backup.json", function (err, data) {
         console.log("Server listening on: http://localhost:%s", port);
     });
 });
+
+
+process.once("SIGINT", function () {
+    console.log("SIGINT received...");
+    stop();
+});
+
+process.once("SIGTERM", function () {
+    console.log("SIGTERM received...");
+    stop();
+});