Skip to content

Commit 6709c3b

Browse files
committed
Graceful shutdown on SIGINT (e.g. from 'pm2 stop').
1 parent 77e994d commit 6709c3b

File tree

3 files changed

+122
-9
lines changed

3 files changed

+122
-9
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
"fast-json-patch": "^3.1.1",
100100
"filesize": "^6.1.0",
101101
"http-proxy-middleware": "^1.0.5",
102+
"http-terminator": "^3.2.0",
102103
"isbot": "^3.6.10",
103104
"js-cookie": "2.2.1",
104105
"js-yaml": "^4.1.0",

server.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import isbot from 'isbot';
3232
import { createCertificate } from 'pem';
3333
import { createServer } from 'https';
3434
import { json } from 'body-parser';
35+
import { createHttpTerminator } from 'http-terminator';
3536

3637
import { readFileSync } from 'fs';
3738
import { join } from 'path';
@@ -487,7 +488,7 @@ function saveToCache(req, page: any) {
487488
*/
488489
function hasNotSucceeded(statusCode) {
489490
const rgx = new RegExp(/^20+/);
490-
return !rgx.test(statusCode)
491+
return !rgx.test(statusCode);
491492
}
492493

493494
function retrieveHeaders(response) {
@@ -525,12 +526,20 @@ function serverStarted() {
525526
* @param keys SSL credentials
526527
*/
527528
function createHttpsServer(keys) {
528-
createServer({
529+
const listener = createServer({
529530
key: keys.serviceKey,
530531
cert: keys.certificate
531532
}, app).listen(environment.ui.port, environment.ui.host, () => {
532533
serverStarted();
533534
});
535+
536+
// Graceful shutdown when signalled
537+
const terminator = createHttpTerminator({server: listener});
538+
process.on('SIGINT', ()=> {
539+
console.debug('Closing HTTPS server on signal');
540+
terminator.terminate().catch(e => { console.error(e); });
541+
console.debug('HTTPS server closed');
542+
});
534543
}
535544

536545
function run() {
@@ -539,9 +548,17 @@ function run() {
539548

540549
// Start up the Node server
541550
const server = app();
542-
server.listen(port, host, () => {
551+
const listener = server.listen(port, host, () => {
543552
serverStarted();
544553
});
554+
555+
// Graceful shutdown when signalled
556+
const terminator = createHttpTerminator({server: listener});
557+
process.on('SIGINT', ()=> {
558+
console.debug('Closing HTTP server on signal');
559+
terminator.terminate().catch(e => { console.error(e); });
560+
console.debug('HTTP server closed.');
561+
});
545562
}
546563

547564
function start() {

yarn.lock

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1761,6 +1761,11 @@
17611761
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.39.0.tgz#58b536bcc843f4cd1e02a7e6171da5c040f4d44b"
17621762
integrity sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==
17631763

1764+
"@fastify/deepmerge@^1.0.0":
1765+
version "1.3.0"
1766+
resolved "https://registry.yarnpkg.com/@fastify/deepmerge/-/deepmerge-1.3.0.tgz#8116858108f0c7d9fd460d05a7d637a13fe3239a"
1767+
integrity sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==
1768+
17641769
"@fortawesome/fontawesome-free@^6.4.0":
17651770
version "6.4.0"
17661771
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.4.0.tgz#1ee0c174e472c84b23cb46c995154dc383e3b4fe"
@@ -3061,9 +3066,9 @@ ajv-keywords@^5.0.0:
30613066
dependencies:
30623067
fast-deep-equal "^3.1.3"
30633068

3064-
ajv@8.12.0, ajv@^8.8.0:
3069+
ajv@8.12.0, ajv@^8.10.0, ajv@^8.8.0:
30653070
version "8.12.0"
3066-
resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz"
3071+
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1"
30673072
integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==
30683073
dependencies:
30693074
fast-deep-equal "^3.1.1"
@@ -3538,6 +3543,11 @@ boolbase@^1.0.0:
35383543
resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz"
35393544
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
35403545

3546+
boolean@^3.1.4:
3547+
version "3.2.0"
3548+
resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b"
3549+
integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==
3550+
35413551
bootstrap@^4.6.1:
35423552
version "4.6.2"
35433553
resolved "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz"
@@ -4641,6 +4651,11 @@ del@^2.2.0:
46414651
pinkie-promise "^2.0.0"
46424652
rimraf "^2.2.8"
46434653

4654+
delay@^5.0.0:
4655+
version "5.0.0"
4656+
resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d"
4657+
integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==
4658+
46444659
delayed-stream@~1.0.0:
46454660
version "1.0.0"
46464661
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
@@ -5579,6 +5594,18 @@ fast-json-stable-stringify@2.1.0, fast-json-stable-stringify@^2.0.0:
55795594
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
55805595
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
55815596

5597+
fast-json-stringify@^5.8.0:
5598+
version "5.8.0"
5599+
resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-5.8.0.tgz#b229ed01ac5f92f3b82001a916c31324652f46d7"
5600+
integrity sha512-VVwK8CFMSALIvt14U8AvrSzQAwN/0vaVRiFFUVlpnXSnDGrSkOAO5MtzyN8oQNjLd5AqTW5OZRgyjoNuAuR3jQ==
5601+
dependencies:
5602+
"@fastify/deepmerge" "^1.0.0"
5603+
ajv "^8.10.0"
5604+
ajv-formats "^2.1.1"
5605+
fast-deep-equal "^3.1.3"
5606+
fast-uri "^2.1.0"
5607+
rfdc "^1.2.0"
5608+
55825609
fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
55835610
version "2.0.6"
55845611
resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
@@ -5589,6 +5616,18 @@ fast-memoize@^2.5.1:
55895616
resolved "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz"
55905617
integrity sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==
55915618

5619+
fast-printf@^1.6.9:
5620+
version "1.6.9"
5621+
resolved "https://registry.yarnpkg.com/fast-printf/-/fast-printf-1.6.9.tgz#212f56570d2dc8ccdd057ee93d50dd414d07d676"
5622+
integrity sha512-FChq8hbz65WMj4rstcQsFB0O7Cy++nmbNfLYnD9cYv2cRn8EG6k/MGn9kO/tjO66t09DLDugj3yL+V2o6Qftrg==
5623+
dependencies:
5624+
boolean "^3.1.4"
5625+
5626+
fast-uri@^2.1.0:
5627+
version "2.2.0"
5628+
resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-2.2.0.tgz#519a0f849bef714aad10e9753d69d8f758f7445a"
5629+
integrity sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg==
5630+
55925631
fastest-levenshtein@^1.0.12:
55935632
version "1.0.16"
55945633
resolved "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz"
@@ -6021,9 +6060,9 @@ globals@^13.19.0:
60216060
dependencies:
60226061
type-fest "^0.20.2"
60236062

6024-
globalthis@^1.0.3:
6063+
globalthis@^1.0.2, globalthis@^1.0.3:
60256064
version "1.0.3"
6026-
resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz"
6065+
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf"
60276066
integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==
60286067
dependencies:
60296068
define-properties "^1.1.3"
@@ -6372,6 +6411,16 @@ http-signature@~1.3.6:
63726411
jsprim "^2.0.2"
63736412
sshpk "^1.14.1"
63746413

6414+
http-terminator@^3.2.0:
6415+
version "3.2.0"
6416+
resolved "https://registry.yarnpkg.com/http-terminator/-/http-terminator-3.2.0.tgz#bc158d2694b733ca4fbf22a35065a81a609fb3e9"
6417+
integrity sha512-JLjck1EzPaWjsmIf8bziM3p9fgR1Y3JoUKAkyYEbZmFrIvJM6I8vVJfBGWlEtV9IWOvzNnaTtjuwZeBY2kwB4g==
6418+
dependencies:
6419+
delay "^5.0.0"
6420+
p-wait-for "^3.2.0"
6421+
roarr "^7.0.4"
6422+
type-fest "^2.3.3"
6423+
63756424
https-proxy-agent@5.0.1, https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1:
63766425
version "5.0.1"
63776426
resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz"
@@ -8609,6 +8658,11 @@ ospath@^1.2.2:
86098658
resolved "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz"
86108659
integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==
86118660

8661+
p-finally@^1.0.0:
8662+
version "1.0.0"
8663+
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
8664+
integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==
8665+
86128666
p-limit@^2.2.0:
86138667
version "2.3.0"
86148668
resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz"
@@ -8652,11 +8706,25 @@ p-retry@^4.5.0:
86528706
"@types/retry" "0.12.0"
86538707
retry "^0.13.1"
86548708

8709+
p-timeout@^3.0.0:
8710+
version "3.2.0"
8711+
resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe"
8712+
integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==
8713+
dependencies:
8714+
p-finally "^1.0.0"
8715+
86558716
p-try@^2.0.0:
86568717
version "2.2.0"
86578718
resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz"
86588719
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
86598720

8721+
p-wait-for@^3.2.0:
8722+
version "3.2.0"
8723+
resolved "https://registry.yarnpkg.com/p-wait-for/-/p-wait-for-3.2.0.tgz#640429bcabf3b0dd9f492c31539c5718cb6a3f1f"
8724+
integrity sha512-wpgERjNkLrBiFmkMEjuZJEWKKDrNfHCKA1OhyN1wg1FrLkULbviEy6py1AyJUgZ72YWFbZ38FIpnqvVqAlDUwA==
8725+
dependencies:
8726+
p-timeout "^3.0.0"
8727+
86608728
pacote@15.1.0:
86618729
version "15.1.0"
86628730
resolved "https://registry.npmjs.org/pacote/-/pacote-15.1.0.tgz"
@@ -9894,9 +9962,9 @@ reusify@^1.0.4:
98949962
resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"
98959963
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
98969964

9897-
rfdc@^1.3.0:
9965+
rfdc@^1.2.0, rfdc@^1.3.0:
98989966
version "1.3.0"
9899-
resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz"
9967+
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
99009968
integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==
99019969

99029970
rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.6.3:
@@ -9913,6 +9981,18 @@ rimraf@^3.0.0, rimraf@^3.0.2:
99139981
dependencies:
99149982
glob "^7.1.3"
99159983

9984+
roarr@^7.0.4:
9985+
version "7.15.1"
9986+
resolved "https://registry.yarnpkg.com/roarr/-/roarr-7.15.1.tgz#e4d93105c37b5ea7dd1200d96a3500f757ddc39f"
9987+
integrity sha512-0ExL9rjOXeQPvQvQo8IcV8SR2GTXmDr1FQFlY2HiAV+gdVQjaVZNOx9d4FI2RqFFsd0sNsiw2TRS/8RU9g0ZfA==
9988+
dependencies:
9989+
boolean "^3.1.4"
9990+
fast-json-stringify "^5.8.0"
9991+
fast-printf "^1.6.9"
9992+
globalthis "^1.0.2"
9993+
safe-stable-stringify "^2.4.3"
9994+
semver-compare "^1.0.0"
9995+
99169996
rtl-css-js@^1.13.1:
99179997
version "1.16.1"
99189998
resolved "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz"
@@ -9995,6 +10075,11 @@ safe-regex-test@^1.0.0:
999510075
get-intrinsic "^1.1.3"
999610076
is-regex "^1.1.4"
999710077

10078+
safe-stable-stringify@^2.4.3:
10079+
version "2.4.3"
10080+
resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886"
10081+
integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==
10082+
999810083
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
999910084
version "2.1.2"
1000010085
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
@@ -10114,6 +10199,11 @@ selfsigned@^2.1.1:
1011410199
dependencies:
1011510200
node-forge "^1"
1011610201

10202+
semver-compare@^1.0.0:
10203+
version "1.0.0"
10204+
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
10205+
integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==
10206+
1011710207
semver@7.3.8:
1011810208
version "7.3.8"
1011910209
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
@@ -11058,6 +11148,11 @@ type-fest@^0.21.3:
1105811148
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz"
1105911149
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
1106011150

11151+
type-fest@^2.3.3:
11152+
version "2.19.0"
11153+
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b"
11154+
integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==
11155+
1106111156
type-is@~1.6.18:
1106211157
version "1.6.18"
1106311158
resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz"

0 commit comments

Comments
 (0)