@proteinjs/server 3.2.1 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/LICENSE +21 -0
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/src/GracefulShutdown.d.ts +52 -0
- package/dist/src/GracefulShutdown.d.ts.map +1 -0
- package/dist/src/GracefulShutdown.js +184 -0
- package/dist/src/GracefulShutdown.js.map +1 -0
- package/dist/src/routes/healthCheck.d.ts +5 -0
- package/dist/src/routes/healthCheck.d.ts.map +1 -1
- package/dist/src/routes/healthCheck.js +10 -0
- package/dist/src/routes/healthCheck.js.map +1 -1
- package/dist/src/startServer.d.ts.map +1 -1
- package/dist/src/startServer.js +6 -1
- package/dist/src/startServer.js.map +1 -1
- package/generated/index.ts +7 -10
- package/index.ts +1 -0
- package/package.json +12 -7
- package/src/GracefulShutdown.ts +132 -0
- package/src/routes/healthCheck.ts +11 -0
- package/src/startServer.ts +4 -0
- package/test/fixture/gracefulShutdownServer.js +42 -0
- package/test/gracefulShutdown.test.ts +190 -0
- package/tsconfig.json +3 -1
- package/dist/jest.config.d.ts +0 -8
- package/dist/jest.config.d.ts.map +0 -1
- package/dist/jest.config.js +0 -11
- package/dist/jest.config.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [3.3.1](https://github.com/proteinjs/server/compare/@proteinjs/server@3.3.0...@proteinjs/server@3.3.1) (2026-08-13)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @proteinjs/server
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [3.3.0](https://github.com/proteinjs/server/compare/@proteinjs/server@3.2.1...@proteinjs/server@3.3.0) (2026-08-12)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* graceful shutdown — SIGTERM drains (readiness 503, bounded, exit 0) ([e98b8bc](https://github.com/proteinjs/server/commit/e98b8bc563d41f6b2cec9d1064c41d27859e98dd))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
6
25
|
# [3.2.0](https://github.com/proteinjs/server/compare/@proteinjs/server@3.1.14...@proteinjs/server@3.2.0) (2026-08-11)
|
|
7
26
|
|
|
8
27
|
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Brent Bahry
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/generated/index.js
CHANGED
|
@@ -33,7 +33,7 @@ require("react-helmet");
|
|
|
33
33
|
require("socket.io");
|
|
34
34
|
require("typescript");
|
|
35
35
|
/** Generate Source Graph */
|
|
36
|
-
var sourceGraph = "{\"options\":{\"directed\":true,\"multigraph\":false,\"compound\":false},\"nodes\":[{\"v\":\"@proteinjs/server/NodeGlobalDataStorage\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"NodeGlobalDataStorage\",\"filePath\":\"/
|
|
36
|
+
var sourceGraph = "{\"options\":{\"directed\":true,\"multigraph\":false,\"compound\":false},\"nodes\":[{\"v\":\"@proteinjs/server/NodeGlobalDataStorage\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"NodeGlobalDataStorage\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/NodeGlobalDataStorage.ts\",\"qualifiedName\":\"@proteinjs/server/NodeGlobalDataStorage\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"HOOK_INITIALIZED\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"GLOBAL_DATA\",\"type\":{\"packageName\":\"@proteinjs/server\",\"name\":\"{ [id: string]: GlobalData }\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server/{ [id: string]: GlobalData }\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"environment\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"setData\",\"returnType\":null,\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"data\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"GlobalData\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/GlobalData\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"getData\",\"returnType\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"GlobalData\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/GlobalData\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"initHook\",\"returnType\":null,\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"GlobalDataStorage\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/GlobalDataStorage\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/server-api/GlobalDataStorage\"},{\"v\":\"@proteinjs/server/NodeSessionDataStorage\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"NodeSessionDataStorage\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/NodeSessionDataStorage.ts\",\"qualifiedName\":\"@proteinjs/server/NodeSessionDataStorage\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"HOOK_INITIALIZED\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"SESSION_DATA\",\"type\":{\"packageName\":\"@proteinjs/server\",\"name\":\"{ [id: string]: SessionData }\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server/{ [id: string]: SessionData }\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"environment\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"setData\",\"returnType\":null,\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"data\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"SessionData\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/SessionData\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"getData\",\"returnType\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"SessionData\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/SessionData\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"initHook\",\"returnType\":null,\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"SessionDataStorage\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/SessionDataStorage\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/server-api/SessionDataStorage\"},{\"v\":\"@proteinjs/server/ExtendedIncomingMessage\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"ExtendedIncomingMessage\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/SocketIOServerRepo.ts\",\"qualifiedName\":\"@proteinjs/server/ExtendedIncomingMessage\",\"properties\":[{\"name\":\"sessionID\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"user\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[],\"typeParameters\":[],\"directParents\":[{\"packageName\":\"http\",\"name\":\"IncomingMessage\",\"filePath\":null,\"qualifiedName\":\"http/IncomingMessage\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"sourceType\":3}},{\"v\":\"http/IncomingMessage\"},{\"v\":\"@proteinjs/server/ExtendedSocket\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"ExtendedSocket\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/SocketIOServerRepo.ts\",\"qualifiedName\":\"@proteinjs/server/ExtendedSocket\",\"properties\":[{\"name\":\"request\",\"type\":{\"packageName\":\"@proteinjs/server\",\"name\":\"ExtendedIncomingMessage\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server/ExtendedIncomingMessage\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[],\"typeParameters\":[],\"directParents\":[{\"packageName\":\"socket.io\",\"name\":\"Socket\",\"filePath\":null,\"qualifiedName\":\"socket.io/Socket\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"sourceType\":3}},{\"v\":\"socket.io/Socket\"},{\"v\":\"@proteinjs/server/environmentCache\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"environmentCache\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/envCache.ts\",\"qualifiedName\":\"@proteinjs/server/environmentCache\",\"type\":{\"packageName\":\"\",\"name\":\"GlobalDataCache<Env>\",\"filePath\":null,\"qualifiedName\":\"/GlobalDataCache<Env>\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"GlobalDataCache\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/GlobalDataCache\",\"typeParameters\":[\"@proteinjs/server-api/Env\"],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/server-api/GlobalDataCache\"},{\"v\":\"@proteinjs/server/healthCheck\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"healthCheck\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/routes/healthCheck.ts\",\"qualifiedName\":\"@proteinjs/server/healthCheck\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/server-api/Route\"}],\"edges\":[{\"v\":\"@proteinjs/server/NodeGlobalDataStorage\",\"w\":\"@proteinjs/server-api/GlobalDataStorage\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/server/NodeSessionDataStorage\",\"w\":\"@proteinjs/server-api/SessionDataStorage\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/server/ExtendedIncomingMessage\",\"w\":\"http/IncomingMessage\",\"value\":\"extends interface\"},{\"v\":\"@proteinjs/server/ExtendedSocket\",\"w\":\"socket.io/Socket\",\"value\":\"extends interface\"},{\"v\":\"@proteinjs/server/environmentCache\",\"w\":\"@proteinjs/server-api/GlobalDataCache\",\"value\":\"has type\"},{\"v\":\"@proteinjs/server/healthCheck\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"}]}";
|
|
37
37
|
/** Generate Source Links */
|
|
38
38
|
var NodeGlobalDataStorage_1 = require("../src/NodeGlobalDataStorage");
|
|
39
39
|
var NodeSessionDataStorage_1 = require("../src/NodeSessionDataStorage");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,4BAA0B;AAC1B,6BAA2B;AAC3B,iCAA+B;AAC/B,iCAA+B;AAC/B,gCAA8B;AAC9B,uBAAqB;AACrB,yBAAuB;AACvB,kBAAgB;AAChB,mBAAiB;AACjB,2BAAyB;AACzB,oBAAkB;AAClB,0BAAwB;AACxB,mBAAiB;AACjB,iBAAe;AACf,wBAAsB;AACtB,qBAAmB;AACnB,sBAAoB;AAGpB,4BAA4B;AAE5B,IAAM,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,4BAA0B;AAC1B,6BAA2B;AAC3B,iCAA+B;AAC/B,iCAA+B;AAC/B,gCAA8B;AAC9B,uBAAqB;AACrB,yBAAuB;AACvB,kBAAgB;AAChB,mBAAiB;AACjB,2BAAyB;AACzB,oBAAkB;AAClB,0BAAwB;AACxB,mBAAiB;AACjB,iBAAe;AACf,wBAAsB;AACtB,qBAAmB;AACnB,sBAAoB;AAGpB,4BAA4B;AAE5B,IAAM,WAAW,GAAG,gqRAAgqR,CAAC;AAGrrR,4BAA4B;AAE5B,sEAAqE;AACrE,wEAAuE;AACvE,4CAAmD;AACnD,yDAAwD;AAExD,IAAM,WAAW,GAAG;IACnB,yCAAyC,EAAE,6CAAqB;IAChE,0CAA0C,EAAE,+CAAsB;IAClE,oCAAoC,EAAE,2BAAgB;IACtD,+BAA+B,EAAE,yBAAW;CAC5C,CAAC;AAGF,kCAAkC;AAElC,oDAAyD;AACzD,6BAAgB,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAGjD,2CAAyB"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./src/startServer"), exports);
|
|
18
|
+
__exportStar(require("./src/GracefulShutdown"), exports);
|
|
18
19
|
__exportStar(require("./src/envCache"), exports);
|
|
19
20
|
__exportStar(require("./src/Request"), exports);
|
|
20
21
|
__exportStar(require("./src/SocketIOServerRepo"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAkC;AAClC,iDAA+B;AAC/B,gDAA8B;AAC9B,2DAAyC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAkC;AAClC,yDAAuC;AACvC,iDAA+B;AAC/B,gDAA8B;AAC9B,2DAAyC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Server as HttpServer } from 'http';
|
|
3
|
+
import { ServerConfig } from '@proteinjs/server-api';
|
|
4
|
+
/**
|
|
5
|
+
* The one owner of the server's shutdown state. Installed by `startServer` before the listener
|
|
6
|
+
* opens; the `/health-check` route reads `isShuttingDown()` — no other flag system exists.
|
|
7
|
+
*
|
|
8
|
+
* Signal / exit-code contract:
|
|
9
|
+
* SIGTERM → drain, then exit 0:
|
|
10
|
+
* 1. `/health-check` flips to 503 immediately while the listener KEEPS accepting for
|
|
11
|
+
* `shutdown.drainDelayMs` — load balancers must OBSERVE the failing readiness and
|
|
12
|
+
* de-register before connections start being refused, or draining becomes user-facing
|
|
13
|
+
* errors. (In Kubernetes, a preStop sleep buys de-registration time BEFORE the SIGTERM
|
|
14
|
+
* even arrives; this window makes the server correct regardless of that wiring.)
|
|
15
|
+
* 2. The listener closes (socket.io clients are disconnected, and `io.close()` closes the
|
|
16
|
+
* http server it is attached to), idle keep-alive connections are closed, and in-flight
|
|
17
|
+
* requests run to completion.
|
|
18
|
+
* 3. The drain is BOUNDED by `shutdown.drainTimeoutMs`: past it, remaining connections are
|
|
19
|
+
* force-closed. Either way the exit code is 0 — a drained shutdown is not a crash.
|
|
20
|
+
* SIGINT → exit 0 immediately (dev ctrl-C: fast and quiet; nothing needs flushing).
|
|
21
|
+
* exit 86 → NOT this class's concern: `process.exit(86)` is the ServePackageSupervisor
|
|
22
|
+
* restart-request contract (a liveness monitor giving up on a dependency); it is not
|
|
23
|
+
* signal-driven and is untouched by these handlers.
|
|
24
|
+
*
|
|
25
|
+
* A SIGTERM before the listener is open (mid-boot kill) exits 0 immediately — nothing is
|
|
26
|
+
* registered anywhere and nothing is in flight.
|
|
27
|
+
*
|
|
28
|
+
* Supervisor compatibility (dev): ServePackageSupervisor SIGTERMs the child's process group and
|
|
29
|
+
* escalates to SIGKILL after its grace period (default 10s); its exit handler ignores exit codes
|
|
30
|
+
* for kills it initiated, so the drain-then-exit-0 shape cannot be misread. DEVELOPMENT defaults
|
|
31
|
+
* `drainDelayMs` to 0 so supervised restarts stay fast.
|
|
32
|
+
*/
|
|
33
|
+
export declare class GracefulShutdown {
|
|
34
|
+
private server;
|
|
35
|
+
private config;
|
|
36
|
+
private static instance?;
|
|
37
|
+
private shuttingDown;
|
|
38
|
+
private logger;
|
|
39
|
+
private constructor();
|
|
40
|
+
/** Install the SIGTERM/SIGINT handlers for this process's server. Idempotent. */
|
|
41
|
+
static install(server: HttpServer, config: ServerConfig): void;
|
|
42
|
+
/** The readiness seam: `/health-check` reports 503 whenever this is true. */
|
|
43
|
+
static isShuttingDown(): boolean;
|
|
44
|
+
private drainAndExit;
|
|
45
|
+
private exitNow;
|
|
46
|
+
private drainDelayMs;
|
|
47
|
+
private drainTimeoutMs;
|
|
48
|
+
/** Await a promise with a deadline; true if it settled in time. */
|
|
49
|
+
private settled;
|
|
50
|
+
private sleep;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=GracefulShutdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GracefulShutdown.d.ts","sourceRoot":"","sources":["../../src/GracefulShutdown.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAIrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,gBAAgB;IAMzB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAmB;IAC3C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAA4C;IAE1D,OAAO;IAKP,iFAAiF;IACjF,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI;IAU9D,6EAA6E;IAC7E,MAAM,CAAC,cAAc,IAAI,OAAO;YAIlB,YAAY;IAwC1B,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,cAAc;IAItB,mEAAmE;YACrD,OAAO;IAUrB,OAAO,CAAC,KAAK;CAGd"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.GracefulShutdown = void 0;
|
|
40
|
+
var logger_1 = require("@proteinjs/logger");
|
|
41
|
+
var SocketIOServerRepo_1 = require("./SocketIOServerRepo");
|
|
42
|
+
/**
|
|
43
|
+
* The one owner of the server's shutdown state. Installed by `startServer` before the listener
|
|
44
|
+
* opens; the `/health-check` route reads `isShuttingDown()` — no other flag system exists.
|
|
45
|
+
*
|
|
46
|
+
* Signal / exit-code contract:
|
|
47
|
+
* SIGTERM → drain, then exit 0:
|
|
48
|
+
* 1. `/health-check` flips to 503 immediately while the listener KEEPS accepting for
|
|
49
|
+
* `shutdown.drainDelayMs` — load balancers must OBSERVE the failing readiness and
|
|
50
|
+
* de-register before connections start being refused, or draining becomes user-facing
|
|
51
|
+
* errors. (In Kubernetes, a preStop sleep buys de-registration time BEFORE the SIGTERM
|
|
52
|
+
* even arrives; this window makes the server correct regardless of that wiring.)
|
|
53
|
+
* 2. The listener closes (socket.io clients are disconnected, and `io.close()` closes the
|
|
54
|
+
* http server it is attached to), idle keep-alive connections are closed, and in-flight
|
|
55
|
+
* requests run to completion.
|
|
56
|
+
* 3. The drain is BOUNDED by `shutdown.drainTimeoutMs`: past it, remaining connections are
|
|
57
|
+
* force-closed. Either way the exit code is 0 — a drained shutdown is not a crash.
|
|
58
|
+
* SIGINT → exit 0 immediately (dev ctrl-C: fast and quiet; nothing needs flushing).
|
|
59
|
+
* exit 86 → NOT this class's concern: `process.exit(86)` is the ServePackageSupervisor
|
|
60
|
+
* restart-request contract (a liveness monitor giving up on a dependency); it is not
|
|
61
|
+
* signal-driven and is untouched by these handlers.
|
|
62
|
+
*
|
|
63
|
+
* A SIGTERM before the listener is open (mid-boot kill) exits 0 immediately — nothing is
|
|
64
|
+
* registered anywhere and nothing is in flight.
|
|
65
|
+
*
|
|
66
|
+
* Supervisor compatibility (dev): ServePackageSupervisor SIGTERMs the child's process group and
|
|
67
|
+
* escalates to SIGKILL after its grace period (default 10s); its exit handler ignores exit codes
|
|
68
|
+
* for kills it initiated, so the drain-then-exit-0 shape cannot be misread. DEVELOPMENT defaults
|
|
69
|
+
* `drainDelayMs` to 0 so supervised restarts stay fast.
|
|
70
|
+
*/
|
|
71
|
+
var GracefulShutdown = /** @class */ (function () {
|
|
72
|
+
function GracefulShutdown(server, config) {
|
|
73
|
+
this.server = server;
|
|
74
|
+
this.config = config;
|
|
75
|
+
this.shuttingDown = false;
|
|
76
|
+
this.logger = new logger_1.Logger({ name: 'GracefulShutdown' });
|
|
77
|
+
}
|
|
78
|
+
/** Install the SIGTERM/SIGINT handlers for this process's server. Idempotent. */
|
|
79
|
+
GracefulShutdown.install = function (server, config) {
|
|
80
|
+
if (GracefulShutdown.instance) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
var instance = new GracefulShutdown(server, config);
|
|
84
|
+
GracefulShutdown.instance = instance;
|
|
85
|
+
process.on('SIGTERM', function () { return void instance.drainAndExit(); });
|
|
86
|
+
process.on('SIGINT', function () { return instance.exitNow(); });
|
|
87
|
+
};
|
|
88
|
+
/** The readiness seam: `/health-check` reports 503 whenever this is true. */
|
|
89
|
+
GracefulShutdown.isShuttingDown = function () {
|
|
90
|
+
var _a, _b;
|
|
91
|
+
return (_b = (_a = GracefulShutdown.instance) === null || _a === void 0 ? void 0 : _a.shuttingDown) !== null && _b !== void 0 ? _b : false;
|
|
92
|
+
};
|
|
93
|
+
GracefulShutdown.prototype.drainAndExit = function () {
|
|
94
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
95
|
+
var drainDelayMs, drainTimeoutMs, drained, io;
|
|
96
|
+
var _this = this;
|
|
97
|
+
return __generator(this, function (_a) {
|
|
98
|
+
switch (_a.label) {
|
|
99
|
+
case 0:
|
|
100
|
+
if (this.shuttingDown) {
|
|
101
|
+
return [2 /*return*/]; // already draining; the sender's escalation is SIGKILL, not a second drain
|
|
102
|
+
}
|
|
103
|
+
this.shuttingDown = true;
|
|
104
|
+
if (!this.server.listening) {
|
|
105
|
+
this.logger.info({ message: "Received SIGTERM before the listener opened \u2014 exiting immediately" });
|
|
106
|
+
process.exit(0);
|
|
107
|
+
}
|
|
108
|
+
drainDelayMs = this.drainDelayMs();
|
|
109
|
+
drainTimeoutMs = this.drainTimeoutMs();
|
|
110
|
+
this.logger.info({
|
|
111
|
+
message: "Received SIGTERM \u2014 /health-check now reports 503; accepting connections for another ".concat(drainDelayMs, "ms, then draining in-flight requests (bound: ").concat(drainTimeoutMs, "ms)"),
|
|
112
|
+
});
|
|
113
|
+
// 1. Readiness-propagation window: the LB observes the 503 while we still serve normally.
|
|
114
|
+
return [4 /*yield*/, this.sleep(drainDelayMs)];
|
|
115
|
+
case 1:
|
|
116
|
+
// 1. Readiness-propagation window: the LB observes the 503 while we still serve normally.
|
|
117
|
+
_a.sent();
|
|
118
|
+
drained = new Promise(function (resolve) { return _this.server.once('close', function () { return resolve(); }); });
|
|
119
|
+
io = SocketIOServerRepo_1.SocketIOServerRepo.getSocketIOServerIfExists();
|
|
120
|
+
if (io) {
|
|
121
|
+
io.close();
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
this.server.close();
|
|
125
|
+
}
|
|
126
|
+
this.server.closeIdleConnections();
|
|
127
|
+
return [4 /*yield*/, this.settled(drained, drainTimeoutMs)];
|
|
128
|
+
case 2:
|
|
129
|
+
// 3. Bounded: past the drain timeout, force-close what remains. Exit 0 either way.
|
|
130
|
+
if (!(_a.sent())) {
|
|
131
|
+
this.logger.warn({
|
|
132
|
+
message: "Drain exceeded its ".concat(drainTimeoutMs, "ms bound \u2014 force-closing the remaining connections"),
|
|
133
|
+
});
|
|
134
|
+
this.server.closeAllConnections();
|
|
135
|
+
}
|
|
136
|
+
this.logger.info({ message: "Drained \u2014 exiting 0" });
|
|
137
|
+
process.exit(0);
|
|
138
|
+
return [2 /*return*/];
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
GracefulShutdown.prototype.exitNow = function () {
|
|
144
|
+
this.shuttingDown = true;
|
|
145
|
+
this.logger.info({ message: "Received SIGINT \u2014 exiting immediately" });
|
|
146
|
+
process.exit(0);
|
|
147
|
+
};
|
|
148
|
+
GracefulShutdown.prototype.drainDelayMs = function () {
|
|
149
|
+
var _a;
|
|
150
|
+
if (typeof ((_a = this.config.shutdown) === null || _a === void 0 ? void 0 : _a.drainDelayMs) === 'number') {
|
|
151
|
+
return this.config.shutdown.drainDelayMs;
|
|
152
|
+
}
|
|
153
|
+
return process.env.DEVELOPMENT ? 0 : 5000;
|
|
154
|
+
};
|
|
155
|
+
GracefulShutdown.prototype.drainTimeoutMs = function () {
|
|
156
|
+
var _a, _b;
|
|
157
|
+
return (_b = (_a = this.config.shutdown) === null || _a === void 0 ? void 0 : _a.drainTimeoutMs) !== null && _b !== void 0 ? _b : 30000;
|
|
158
|
+
};
|
|
159
|
+
/** Await a promise with a deadline; true if it settled in time. */
|
|
160
|
+
GracefulShutdown.prototype.settled = function (promise, ms) {
|
|
161
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
162
|
+
var timer, timedOut, result;
|
|
163
|
+
return __generator(this, function (_a) {
|
|
164
|
+
switch (_a.label) {
|
|
165
|
+
case 0:
|
|
166
|
+
timedOut = new Promise(function (resolve) {
|
|
167
|
+
timer = setTimeout(function () { return resolve(false); }, ms);
|
|
168
|
+
});
|
|
169
|
+
return [4 /*yield*/, Promise.race([promise.then(function () { return true; }), timedOut])];
|
|
170
|
+
case 1:
|
|
171
|
+
result = _a.sent();
|
|
172
|
+
clearTimeout(timer);
|
|
173
|
+
return [2 /*return*/, result];
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
GracefulShutdown.prototype.sleep = function (ms) {
|
|
179
|
+
return new Promise(function (resolve) { return setTimeout(resolve, ms); });
|
|
180
|
+
};
|
|
181
|
+
return GracefulShutdown;
|
|
182
|
+
}());
|
|
183
|
+
exports.GracefulShutdown = GracefulShutdown;
|
|
184
|
+
//# sourceMappingURL=GracefulShutdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GracefulShutdown.js","sourceRoot":"","sources":["../../src/GracefulShutdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import { Route } from '@proteinjs/server-api';
|
|
2
|
+
/**
|
|
3
|
+
* Readiness: 200 while serving, 503 once GracefulShutdown has begun draining (SIGTERM
|
|
4
|
+
* received) — load balancers and kubelet readiness probes read this route, and the 503 is
|
|
5
|
+
* what makes them stop routing new traffic while in-flight requests finish.
|
|
6
|
+
*/
|
|
2
7
|
export declare const healthCheck: Route;
|
|
3
8
|
//# sourceMappingURL=healthCheck.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"healthCheck.d.ts","sourceRoot":"","sources":["../../../src/routes/healthCheck.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"healthCheck.d.ts","sourceRoot":"","sources":["../../../src/routes/healthCheck.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAG9C;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,KAYzB,CAAC"}
|
|
@@ -37,12 +37,22 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.healthCheck = void 0;
|
|
40
|
+
var GracefulShutdown_1 = require("../GracefulShutdown");
|
|
41
|
+
/**
|
|
42
|
+
* Readiness: 200 while serving, 503 once GracefulShutdown has begun draining (SIGTERM
|
|
43
|
+
* received) — load balancers and kubelet readiness probes read this route, and the 503 is
|
|
44
|
+
* what makes them stop routing new traffic while in-flight requests finish.
|
|
45
|
+
*/
|
|
40
46
|
exports.healthCheck = {
|
|
41
47
|
path: 'health-check',
|
|
42
48
|
method: 'get',
|
|
43
49
|
useHttp: true,
|
|
44
50
|
onRequest: function (request, response) { return __awaiter(void 0, void 0, void 0, function () {
|
|
45
51
|
return __generator(this, function (_a) {
|
|
52
|
+
if (GracefulShutdown_1.GracefulShutdown.isShuttingDown()) {
|
|
53
|
+
response.status(503).send('draining');
|
|
54
|
+
return [2 /*return*/];
|
|
55
|
+
}
|
|
46
56
|
response.send();
|
|
47
57
|
return [2 /*return*/];
|
|
48
58
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"healthCheck.js","sourceRoot":"","sources":["../../../src/routes/healthCheck.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"healthCheck.js","sourceRoot":"","sources":["../../../src/routes/healthCheck.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,wDAAuD;AAEvD;;;;GAIG;AACU,QAAA,WAAW,GAAU;IAChC,IAAI,EAAE,cAAc;IACpB,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,UAAO,OAAO,EAAE,QAAQ;;YACjC,IAAI,mCAAgB,CAAC,cAAc,EAAE,EAAE;gBACrC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACtC,sBAAO;aACR;YAED,QAAQ,CAAC,IAAI,EAAE,CAAC;;;SACjB;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startServer.d.ts","sourceRoot":"","sources":["../../src/startServer.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,YAAY,EAKb,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"startServer.d.ts","sourceRoot":"","sources":["../../src/startServer.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,YAAY,EAKb,MAAM,uBAAuB,CAAC;AAY/B,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,iBA2CrD"}
|
package/dist/src/startServer.js
CHANGED
|
@@ -65,6 +65,7 @@ var loadRoutes_1 = require("./loadRoutes");
|
|
|
65
65
|
var logger_1 = require("@proteinjs/logger");
|
|
66
66
|
var SocketIOServerRepo_1 = require("./SocketIOServerRepo");
|
|
67
67
|
var DevClientBuild_1 = require("./DevClientBuild");
|
|
68
|
+
var GracefulShutdown_1 = require("./GracefulShutdown");
|
|
68
69
|
var staticContentPath = '/static/';
|
|
69
70
|
var logger = new logger_1.Logger({ name: 'Server' });
|
|
70
71
|
var app = (0, express_1.default)();
|
|
@@ -74,7 +75,11 @@ function startServer(config) {
|
|
|
74
75
|
var routes, clientBuildReady, globalData, _i, _a, globalDataCache, _b, _c;
|
|
75
76
|
return __generator(this, function (_d) {
|
|
76
77
|
switch (_d.label) {
|
|
77
|
-
case 0:
|
|
78
|
+
case 0:
|
|
79
|
+
// First, before any (possibly long) startup work: a SIGTERM must drain gracefully from the
|
|
80
|
+
// moment this process can be part of a rollout, including mid-boot.
|
|
81
|
+
GracefulShutdown_1.GracefulShutdown.install(server, config);
|
|
82
|
+
return [4 /*yield*/, runStartupTasks('before server config')];
|
|
78
83
|
case 1:
|
|
79
84
|
_d.sent();
|
|
80
85
|
routes = (0, server_api_1.getRoutes)();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startServer.js","sourceRoot":"","sources":["../../src/startServer.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"startServer.js","sourceRoot":"","sources":["../../src/startServer.ts"],"names":[],"mappings":"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"}
|
package/generated/index.ts
CHANGED
|
@@ -18,11 +18,10 @@ import 'react-helmet';
|
|
|
18
18
|
import 'socket.io';
|
|
19
19
|
import 'typescript';
|
|
20
20
|
|
|
21
|
-
|
|
22
21
|
/** Generate Source Graph */
|
|
23
22
|
|
|
24
|
-
const sourceGraph =
|
|
25
|
-
|
|
23
|
+
const sourceGraph =
|
|
24
|
+
'{"options":{"directed":true,"multigraph":false,"compound":false},"nodes":[{"v":"@proteinjs/server/NodeGlobalDataStorage","value":{"packageName":"@proteinjs/server","name":"NodeGlobalDataStorage","filePath":"/home/runner/work/server/server/packages/server/src/NodeGlobalDataStorage.ts","qualifiedName":"@proteinjs/server/NodeGlobalDataStorage","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"HOOK_INITIALIZED","type":null,"isOptional":false,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"GLOBAL_DATA","type":{"packageName":"@proteinjs/server","name":"{ [id: string]: GlobalData }","filePath":null,"qualifiedName":"@proteinjs/server/{ [id: string]: GlobalData }","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"environment","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[{"name":"setData","returnType":null,"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"data","type":{"packageName":"@proteinjs/server-api","name":"GlobalData","filePath":null,"qualifiedName":"@proteinjs/server-api/GlobalData","typeParameters":null,"directParents":null}}]},{"name":"getData","returnType":{"packageName":"@proteinjs/server-api","name":"GlobalData","filePath":null,"qualifiedName":"@proteinjs/server-api/GlobalData","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]},{"name":"initHook","returnType":null,"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/server-api","name":"GlobalDataStorage","filePath":null,"qualifiedName":"@proteinjs/server-api/GlobalDataStorage","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/server-api/GlobalDataStorage"},{"v":"@proteinjs/server/NodeSessionDataStorage","value":{"packageName":"@proteinjs/server","name":"NodeSessionDataStorage","filePath":"/home/runner/work/server/server/packages/server/src/NodeSessionDataStorage.ts","qualifiedName":"@proteinjs/server/NodeSessionDataStorage","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"HOOK_INITIALIZED","type":null,"isOptional":false,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"SESSION_DATA","type":{"packageName":"@proteinjs/server","name":"{ [id: string]: SessionData }","filePath":null,"qualifiedName":"@proteinjs/server/{ [id: string]: SessionData }","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"environment","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[{"name":"setData","returnType":null,"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"data","type":{"packageName":"@proteinjs/server-api","name":"SessionData","filePath":null,"qualifiedName":"@proteinjs/server-api/SessionData","typeParameters":null,"directParents":null}}]},{"name":"getData","returnType":{"packageName":"@proteinjs/server-api","name":"SessionData","filePath":null,"qualifiedName":"@proteinjs/server-api/SessionData","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]},{"name":"initHook","returnType":null,"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/server-api","name":"SessionDataStorage","filePath":null,"qualifiedName":"@proteinjs/server-api/SessionDataStorage","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/server-api/SessionDataStorage"},{"v":"@proteinjs/server/ExtendedIncomingMessage","value":{"packageName":"@proteinjs/server","name":"ExtendedIncomingMessage","filePath":"/home/runner/work/server/server/packages/server/src/SocketIOServerRepo.ts","qualifiedName":"@proteinjs/server/ExtendedIncomingMessage","properties":[{"name":"sessionID","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"user","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[],"typeParameters":[],"directParents":[{"packageName":"http","name":"IncomingMessage","filePath":null,"qualifiedName":"http/IncomingMessage","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"sourceType":3}},{"v":"http/IncomingMessage"},{"v":"@proteinjs/server/ExtendedSocket","value":{"packageName":"@proteinjs/server","name":"ExtendedSocket","filePath":"/home/runner/work/server/server/packages/server/src/SocketIOServerRepo.ts","qualifiedName":"@proteinjs/server/ExtendedSocket","properties":[{"name":"request","type":{"packageName":"@proteinjs/server","name":"ExtendedIncomingMessage","filePath":null,"qualifiedName":"@proteinjs/server/ExtendedIncomingMessage","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[],"typeParameters":[],"directParents":[{"packageName":"socket.io","name":"Socket","filePath":null,"qualifiedName":"socket.io/Socket","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"sourceType":3}},{"v":"socket.io/Socket"},{"v":"@proteinjs/server/environmentCache","value":{"packageName":"@proteinjs/server","name":"environmentCache","filePath":"/home/runner/work/server/server/packages/server/src/envCache.ts","qualifiedName":"@proteinjs/server/environmentCache","type":{"packageName":"","name":"GlobalDataCache<Env>","filePath":null,"qualifiedName":"/GlobalDataCache<Env>","typeParameters":[],"directParents":[{"packageName":"@proteinjs/server-api","name":"GlobalDataCache","filePath":null,"qualifiedName":"@proteinjs/server-api/GlobalDataCache","typeParameters":["@proteinjs/server-api/Env"],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/server-api/GlobalDataCache"},{"v":"@proteinjs/server/healthCheck","value":{"packageName":"@proteinjs/server","name":"healthCheck","filePath":"/home/runner/work/server/server/packages/server/src/routes/healthCheck.ts","qualifiedName":"@proteinjs/server/healthCheck","type":{"packageName":"@proteinjs/server-api","name":"Route","filePath":null,"qualifiedName":"@proteinjs/server-api/Route","typeParameters":[],"directParents":[{"packageName":"@proteinjs/server-api","name":"Route","filePath":null,"qualifiedName":"@proteinjs/server-api/Route","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/server-api/Route"}],"edges":[{"v":"@proteinjs/server/NodeGlobalDataStorage","w":"@proteinjs/server-api/GlobalDataStorage","value":"implements interface"},{"v":"@proteinjs/server/NodeSessionDataStorage","w":"@proteinjs/server-api/SessionDataStorage","value":"implements interface"},{"v":"@proteinjs/server/ExtendedIncomingMessage","w":"http/IncomingMessage","value":"extends interface"},{"v":"@proteinjs/server/ExtendedSocket","w":"socket.io/Socket","value":"extends interface"},{"v":"@proteinjs/server/environmentCache","w":"@proteinjs/server-api/GlobalDataCache","value":"has type"},{"v":"@proteinjs/server/healthCheck","w":"@proteinjs/server-api/Route","value":"has type"}]}';
|
|
26
25
|
|
|
27
26
|
/** Generate Source Links */
|
|
28
27
|
|
|
@@ -32,17 +31,15 @@ import { environmentCache } from '../src/envCache';
|
|
|
32
31
|
import { healthCheck } from '../src/routes/healthCheck';
|
|
33
32
|
|
|
34
33
|
const sourceLinks = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
'@proteinjs/server/NodeGlobalDataStorage': NodeGlobalDataStorage,
|
|
35
|
+
'@proteinjs/server/NodeSessionDataStorage': NodeSessionDataStorage,
|
|
36
|
+
'@proteinjs/server/environmentCache': environmentCache,
|
|
37
|
+
'@proteinjs/server/healthCheck': healthCheck,
|
|
39
38
|
};
|
|
40
39
|
|
|
41
|
-
|
|
42
40
|
/** Load Source Graph and Links */
|
|
43
41
|
|
|
44
42
|
import { SourceRepository } from '@proteinjs/reflection';
|
|
45
43
|
SourceRepository.merge(sourceGraph, sourceLinks);
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
export * from '../index';
|
|
45
|
+
export * from '../index';
|
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteinjs/server",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"description": "A server impl",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -18,13 +18,14 @@
|
|
|
18
18
|
"scripts": {
|
|
19
19
|
"clean": "rm -rf dist/ generated/ node_modules/",
|
|
20
20
|
"build": "reflection-build && tsc",
|
|
21
|
-
"watch": "reflection-watch"
|
|
21
|
+
"watch": "reflection-watch",
|
|
22
|
+
"test": "jest --runInBand"
|
|
22
23
|
},
|
|
23
24
|
"dependencies": {
|
|
24
|
-
"@proteinjs/event": "^1.0.
|
|
25
|
+
"@proteinjs/event": "^1.0.18",
|
|
25
26
|
"@proteinjs/logger": "^1.0.21",
|
|
26
27
|
"@proteinjs/reflection": "^1.1.12",
|
|
27
|
-
"@proteinjs/server-api": "^3.
|
|
28
|
+
"@proteinjs/server-api": "^3.1.1",
|
|
28
29
|
"@proteinjs/util-node": "^1.10.1",
|
|
29
30
|
"body-parser": "1.19.0",
|
|
30
31
|
"cookie-parser": "1.4.5",
|
|
@@ -45,7 +46,8 @@
|
|
|
45
46
|
"@types/cookie-parser": "1.4.2",
|
|
46
47
|
"@types/express": "4.17.7",
|
|
47
48
|
"@types/express-session": "1.17.0",
|
|
48
|
-
"@types/
|
|
49
|
+
"@types/jest": "29.5.5",
|
|
50
|
+
"@types/node": "^20.11.0",
|
|
49
51
|
"@types/passport": "1.0.4",
|
|
50
52
|
"@types/passport-local": "1.0.33",
|
|
51
53
|
"@types/react": "18.2.23",
|
|
@@ -56,8 +58,11 @@
|
|
|
56
58
|
"@typescript-eslint/parser": "7.8.0",
|
|
57
59
|
"eslint": "8.57.0",
|
|
58
60
|
"eslint-config-prettier": "9.1.0",
|
|
59
|
-
"eslint-plugin-prettier": "5.1.3"
|
|
61
|
+
"eslint-plugin-prettier": "5.1.3",
|
|
62
|
+
"jest": "29.7.0",
|
|
63
|
+
"ts-jest": "29.1.1"
|
|
60
64
|
},
|
|
61
65
|
"main": "./dist/generated/index.js",
|
|
62
|
-
"types": "./dist/generated/index.d.ts"
|
|
66
|
+
"types": "./dist/generated/index.d.ts",
|
|
67
|
+
"gitHead": "3182b24b4fc245548a39cf3eb689c5cd64f318f1"
|
|
63
68
|
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Server as HttpServer } from 'http';
|
|
2
|
+
import { ServerConfig } from '@proteinjs/server-api';
|
|
3
|
+
import { Logger } from '@proteinjs/logger';
|
|
4
|
+
import { SocketIOServerRepo } from './SocketIOServerRepo';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The one owner of the server's shutdown state. Installed by `startServer` before the listener
|
|
8
|
+
* opens; the `/health-check` route reads `isShuttingDown()` — no other flag system exists.
|
|
9
|
+
*
|
|
10
|
+
* Signal / exit-code contract:
|
|
11
|
+
* SIGTERM → drain, then exit 0:
|
|
12
|
+
* 1. `/health-check` flips to 503 immediately while the listener KEEPS accepting for
|
|
13
|
+
* `shutdown.drainDelayMs` — load balancers must OBSERVE the failing readiness and
|
|
14
|
+
* de-register before connections start being refused, or draining becomes user-facing
|
|
15
|
+
* errors. (In Kubernetes, a preStop sleep buys de-registration time BEFORE the SIGTERM
|
|
16
|
+
* even arrives; this window makes the server correct regardless of that wiring.)
|
|
17
|
+
* 2. The listener closes (socket.io clients are disconnected, and `io.close()` closes the
|
|
18
|
+
* http server it is attached to), idle keep-alive connections are closed, and in-flight
|
|
19
|
+
* requests run to completion.
|
|
20
|
+
* 3. The drain is BOUNDED by `shutdown.drainTimeoutMs`: past it, remaining connections are
|
|
21
|
+
* force-closed. Either way the exit code is 0 — a drained shutdown is not a crash.
|
|
22
|
+
* SIGINT → exit 0 immediately (dev ctrl-C: fast and quiet; nothing needs flushing).
|
|
23
|
+
* exit 86 → NOT this class's concern: `process.exit(86)` is the ServePackageSupervisor
|
|
24
|
+
* restart-request contract (a liveness monitor giving up on a dependency); it is not
|
|
25
|
+
* signal-driven and is untouched by these handlers.
|
|
26
|
+
*
|
|
27
|
+
* A SIGTERM before the listener is open (mid-boot kill) exits 0 immediately — nothing is
|
|
28
|
+
* registered anywhere and nothing is in flight.
|
|
29
|
+
*
|
|
30
|
+
* Supervisor compatibility (dev): ServePackageSupervisor SIGTERMs the child's process group and
|
|
31
|
+
* escalates to SIGKILL after its grace period (default 10s); its exit handler ignores exit codes
|
|
32
|
+
* for kills it initiated, so the drain-then-exit-0 shape cannot be misread. DEVELOPMENT defaults
|
|
33
|
+
* `drainDelayMs` to 0 so supervised restarts stay fast.
|
|
34
|
+
*/
|
|
35
|
+
export class GracefulShutdown {
|
|
36
|
+
private static instance?: GracefulShutdown;
|
|
37
|
+
private shuttingDown = false;
|
|
38
|
+
private logger = new Logger({ name: 'GracefulShutdown' });
|
|
39
|
+
|
|
40
|
+
private constructor(
|
|
41
|
+
private server: HttpServer,
|
|
42
|
+
private config: ServerConfig
|
|
43
|
+
) {}
|
|
44
|
+
|
|
45
|
+
/** Install the SIGTERM/SIGINT handlers for this process's server. Idempotent. */
|
|
46
|
+
static install(server: HttpServer, config: ServerConfig): void {
|
|
47
|
+
if (GracefulShutdown.instance) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const instance = new GracefulShutdown(server, config);
|
|
51
|
+
GracefulShutdown.instance = instance;
|
|
52
|
+
process.on('SIGTERM', () => void instance.drainAndExit());
|
|
53
|
+
process.on('SIGINT', () => instance.exitNow());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The readiness seam: `/health-check` reports 503 whenever this is true. */
|
|
57
|
+
static isShuttingDown(): boolean {
|
|
58
|
+
return GracefulShutdown.instance?.shuttingDown ?? false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private async drainAndExit(): Promise<void> {
|
|
62
|
+
if (this.shuttingDown) {
|
|
63
|
+
return; // already draining; the sender's escalation is SIGKILL, not a second drain
|
|
64
|
+
}
|
|
65
|
+
this.shuttingDown = true;
|
|
66
|
+
if (!this.server.listening) {
|
|
67
|
+
this.logger.info({ message: `Received SIGTERM before the listener opened — exiting immediately` });
|
|
68
|
+
process.exit(0);
|
|
69
|
+
}
|
|
70
|
+
const drainDelayMs = this.drainDelayMs();
|
|
71
|
+
const drainTimeoutMs = this.drainTimeoutMs();
|
|
72
|
+
this.logger.info({
|
|
73
|
+
message: `Received SIGTERM — /health-check now reports 503; accepting connections for another ${drainDelayMs}ms, then draining in-flight requests (bound: ${drainTimeoutMs}ms)`,
|
|
74
|
+
});
|
|
75
|
+
// 1. Readiness-propagation window: the LB observes the 503 while we still serve normally.
|
|
76
|
+
await this.sleep(drainDelayMs);
|
|
77
|
+
// 2. Stop accepting and drain. The http 'close' event is the drain-complete signal (it
|
|
78
|
+
// fires once the listener is closed AND every connection has ended). socket.io's close()
|
|
79
|
+
// disconnects its clients (websockets would otherwise hold the drain open forever) and
|
|
80
|
+
// closes the http server it is attached to; closeIdleConnections reaps keep-alive
|
|
81
|
+
// connections that are between requests. In-flight requests run to completion.
|
|
82
|
+
const drained = new Promise<void>((resolve) => this.server.once('close', () => resolve()));
|
|
83
|
+
const io = SocketIOServerRepo.getSocketIOServerIfExists();
|
|
84
|
+
if (io) {
|
|
85
|
+
io.close();
|
|
86
|
+
} else {
|
|
87
|
+
this.server.close();
|
|
88
|
+
}
|
|
89
|
+
this.server.closeIdleConnections();
|
|
90
|
+
// 3. Bounded: past the drain timeout, force-close what remains. Exit 0 either way.
|
|
91
|
+
if (!(await this.settled(drained, drainTimeoutMs))) {
|
|
92
|
+
this.logger.warn({
|
|
93
|
+
message: `Drain exceeded its ${drainTimeoutMs}ms bound — force-closing the remaining connections`,
|
|
94
|
+
});
|
|
95
|
+
this.server.closeAllConnections();
|
|
96
|
+
}
|
|
97
|
+
this.logger.info({ message: `Drained — exiting 0` });
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private exitNow(): void {
|
|
102
|
+
this.shuttingDown = true;
|
|
103
|
+
this.logger.info({ message: `Received SIGINT — exiting immediately` });
|
|
104
|
+
process.exit(0);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private drainDelayMs(): number {
|
|
108
|
+
if (typeof this.config.shutdown?.drainDelayMs === 'number') {
|
|
109
|
+
return this.config.shutdown.drainDelayMs;
|
|
110
|
+
}
|
|
111
|
+
return process.env.DEVELOPMENT ? 0 : 5000;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private drainTimeoutMs(): number {
|
|
115
|
+
return this.config.shutdown?.drainTimeoutMs ?? 30_000;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Await a promise with a deadline; true if it settled in time. */
|
|
119
|
+
private async settled(promise: Promise<void>, ms: number): Promise<boolean> {
|
|
120
|
+
let timer: NodeJS.Timeout | undefined;
|
|
121
|
+
const timedOut = new Promise<boolean>((resolve) => {
|
|
122
|
+
timer = setTimeout(() => resolve(false), ms);
|
|
123
|
+
});
|
|
124
|
+
const result = await Promise.race([promise.then(() => true), timedOut]);
|
|
125
|
+
clearTimeout(timer);
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private sleep(ms: number): Promise<void> {
|
|
130
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import { Route } from '@proteinjs/server-api';
|
|
2
|
+
import { GracefulShutdown } from '../GracefulShutdown';
|
|
2
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Readiness: 200 while serving, 503 once GracefulShutdown has begun draining (SIGTERM
|
|
6
|
+
* received) — load balancers and kubelet readiness probes read this route, and the 503 is
|
|
7
|
+
* what makes them stop routing new traffic while in-flight requests finish.
|
|
8
|
+
*/
|
|
3
9
|
export const healthCheck: Route = {
|
|
4
10
|
path: 'health-check',
|
|
5
11
|
method: 'get',
|
|
6
12
|
useHttp: true,
|
|
7
13
|
onRequest: async (request, response): Promise<void> => {
|
|
14
|
+
if (GracefulShutdown.isShuttingDown()) {
|
|
15
|
+
response.status(503).send('draining');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
8
19
|
response.send();
|
|
9
20
|
},
|
|
10
21
|
};
|
package/src/startServer.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { loadRoutes, loadDefaultStarRoute } from './loadRoutes';
|
|
|
20
20
|
import { Logger } from '@proteinjs/logger';
|
|
21
21
|
import { SocketIOServerRepo, ExtendedSocket } from './SocketIOServerRepo';
|
|
22
22
|
import { DevClientBuild } from './DevClientBuild';
|
|
23
|
+
import { GracefulShutdown } from './GracefulShutdown';
|
|
23
24
|
|
|
24
25
|
const staticContentPath = '/static/';
|
|
25
26
|
const logger = new Logger({ name: 'Server' });
|
|
@@ -27,6 +28,9 @@ const app = express();
|
|
|
27
28
|
const server = new HttpServer(app);
|
|
28
29
|
|
|
29
30
|
export async function startServer(config: ServerConfig) {
|
|
31
|
+
// First, before any (possibly long) startup work: a SIGTERM must drain gracefully from the
|
|
32
|
+
// moment this process can be part of a rollout, including mid-boot.
|
|
33
|
+
GracefulShutdown.install(server, config);
|
|
30
34
|
await runStartupTasks('before server config');
|
|
31
35
|
const routes = getRoutes();
|
|
32
36
|
configureRequests(app);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test fixture: a REAL @proteinjs/server (the built dist — the same code prod runs) with a
|
|
3
|
+
* deliberately slow endpoint, so the graceful-shutdown suite can hold a request in flight
|
|
4
|
+
* while it signals the process. Run with:
|
|
5
|
+
* FIXTURE_PORT=<port> [FIXTURE_DRAIN_DELAY_MS=..] [FIXTURE_DRAIN_TIMEOUT_MS=..] node gracefulShutdownServer.js
|
|
6
|
+
*
|
|
7
|
+
* Markers on stdout (the suite's synchronization points):
|
|
8
|
+
* FIXTURE_READY — startServer resolved (the listener is up)
|
|
9
|
+
* SLOW_REQUEST_STARTED — the /slow handler is executing (a request is now in flight)
|
|
10
|
+
*/
|
|
11
|
+
const expressSession = require('express-session');
|
|
12
|
+
const { startServer } = require('../../dist/generated/index.js');
|
|
13
|
+
|
|
14
|
+
const port = Number(process.env.FIXTURE_PORT);
|
|
15
|
+
if (!port) {
|
|
16
|
+
throw new Error('FIXTURE_PORT is required');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
startServer({
|
|
20
|
+
port,
|
|
21
|
+
session: { secret: 'graceful-shutdown-test', store: new expressSession.MemoryStore() },
|
|
22
|
+
request: {
|
|
23
|
+
disableRequestLogging: true,
|
|
24
|
+
// The slow endpoint rides the beforeRequest middleware seam so the fixture needs no
|
|
25
|
+
// reflection-registered Route of its own: it answers /slow itself (never calls next)
|
|
26
|
+
// after ?ms= of held work, standing in for any long in-flight request.
|
|
27
|
+
beforeRequest: async (request, response, next) => {
|
|
28
|
+
if (request.path !== '/slow') {
|
|
29
|
+
next();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
console.log('SLOW_REQUEST_STARTED');
|
|
33
|
+
const ms = Number(request.query.ms ?? 3000);
|
|
34
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
35
|
+
response.status(200).send('slow-done');
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
shutdown: {
|
|
39
|
+
drainDelayMs: process.env.FIXTURE_DRAIN_DELAY_MS ? Number(process.env.FIXTURE_DRAIN_DELAY_MS) : undefined,
|
|
40
|
+
drainTimeoutMs: process.env.FIXTURE_DRAIN_TIMEOUT_MS ? Number(process.env.FIXTURE_DRAIN_TIMEOUT_MS) : undefined,
|
|
41
|
+
},
|
|
42
|
+
}).then(() => console.log('FIXTURE_READY'));
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import * as http from 'http';
|
|
2
|
+
import * as net from 'net';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { ChildProcess, spawn } from 'child_process';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Graceful-shutdown contract of a real server process (spawns the built dist — run
|
|
8
|
+
* `npm run build` first). The exit-code/signal contract these tests pin down:
|
|
9
|
+
*
|
|
10
|
+
* SIGTERM → readiness (/health-check) flips to 503 immediately while the listener stays
|
|
11
|
+
* open for shutdown.drainDelayMs (LBs observe the failing readiness and drain),
|
|
12
|
+
* then the listener closes (new connections refused), in-flight requests COMPLETE,
|
|
13
|
+
* idle keep-alives are closed, and the process exits 0 — bounded by
|
|
14
|
+
* shutdown.drainTimeoutMs (past it, remaining connections are force-closed and
|
|
15
|
+
* the exit is still 0).
|
|
16
|
+
* SIGINT → immediate exit 0 (dev ctrl-C: fast, quiet).
|
|
17
|
+
* exit 86 → RESTART_REQUEST_EXIT_CODE, untouched by this feature: process.exit(86) is not
|
|
18
|
+
* signal-driven (ServePackageSupervisor's respawn contract rides it).
|
|
19
|
+
*/
|
|
20
|
+
const packageRoot = path.join(__dirname, '..');
|
|
21
|
+
const fixturePath = path.join(__dirname, 'fixture', 'gracefulShutdownServer.js');
|
|
22
|
+
|
|
23
|
+
type Fixture = {
|
|
24
|
+
child: ChildProcess;
|
|
25
|
+
port: number;
|
|
26
|
+
stdout: () => string;
|
|
27
|
+
waitForMarker: (marker: string, timeoutMs?: number) => Promise<void>;
|
|
28
|
+
exited: Promise<{ code: number | null; signal: NodeJS.Signals | null }>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
describe('graceful shutdown', () => {
|
|
32
|
+
let fixture: Fixture | undefined;
|
|
33
|
+
|
|
34
|
+
afterEach(async () => {
|
|
35
|
+
if (fixture && fixture.child.exitCode === null && fixture.child.signalCode === null) {
|
|
36
|
+
fixture.child.kill('SIGKILL');
|
|
37
|
+
await fixture.exited.catch(() => undefined);
|
|
38
|
+
}
|
|
39
|
+
fixture = undefined;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('SIGTERM: health flips to 503, in-flight request completes, new connections refused after the delay, exit 0 within the bound', async () => {
|
|
43
|
+
// Generous drain delay so the 503 window is deterministic on slow CI runners.
|
|
44
|
+
fixture = await startFixture({ drainDelayMs: 3000, drainTimeoutMs: 10000 });
|
|
45
|
+
|
|
46
|
+
// Hold a request in flight (6s — longer than the 3s drain delay, well under the bound).
|
|
47
|
+
const slow = request(fixture.port, '/slow?ms=6000');
|
|
48
|
+
slow.catch(() => undefined); // an assertion failing earlier SIGKILLs the fixture — keep that teardown from surfacing as an unhandled rejection
|
|
49
|
+
await fixture.waitForMarker('SLOW_REQUEST_STARTED');
|
|
50
|
+
|
|
51
|
+
const sigtermAt = Date.now();
|
|
52
|
+
fixture.child.kill('SIGTERM');
|
|
53
|
+
|
|
54
|
+
// 1. Readiness fails IMMEDIATELY: a fresh connection inside the drain-delay window gets 503.
|
|
55
|
+
const during = await request(fixture.port, '/health-check');
|
|
56
|
+
expect(during.status).toBe(503);
|
|
57
|
+
expect(Date.now() - sigtermAt).toBeLessThan(3000); // still inside the delay window
|
|
58
|
+
|
|
59
|
+
// 2. After the delay the listener is closed: new connections are refused while the
|
|
60
|
+
// in-flight request is still draining.
|
|
61
|
+
await sleep(sigtermAt + 4000 - Date.now());
|
|
62
|
+
await expect(request(fixture.port, '/health-check')).rejects.toMatchObject({
|
|
63
|
+
code: expect.stringMatching(/ECONNREFUSED|ECONNRESET/),
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// 3. The in-flight request COMPLETES with its full response.
|
|
67
|
+
const slowResult = await slow;
|
|
68
|
+
expect(slowResult.status).toBe(200);
|
|
69
|
+
expect(slowResult.body).toBe('slow-done');
|
|
70
|
+
|
|
71
|
+
// 4. The process exits 0 shortly after the drain completes — the drain ended it, not the
|
|
72
|
+
// timeout (slow done at ~6s; bound would land at ~13s).
|
|
73
|
+
const exit = await fixture.exited;
|
|
74
|
+
expect(exit).toEqual({ code: 0, signal: null });
|
|
75
|
+
expect(Date.now() - sigtermAt).toBeLessThan(10000);
|
|
76
|
+
}, 30000);
|
|
77
|
+
|
|
78
|
+
it('SIGTERM: the drain is BOUNDED — a request longer than drainTimeoutMs is force-closed and the exit is still 0', async () => {
|
|
79
|
+
fixture = await startFixture({ drainDelayMs: 0, drainTimeoutMs: 3000 });
|
|
80
|
+
|
|
81
|
+
// In-flight request that would outlive the bound by far.
|
|
82
|
+
const slow = request(fixture.port, '/slow?ms=60000').catch((e) => e);
|
|
83
|
+
await fixture.waitForMarker('SLOW_REQUEST_STARTED');
|
|
84
|
+
|
|
85
|
+
const sigtermAt = Date.now();
|
|
86
|
+
fixture.child.kill('SIGTERM');
|
|
87
|
+
|
|
88
|
+
const exit = await fixture.exited;
|
|
89
|
+
expect(exit).toEqual({ code: 0, signal: null });
|
|
90
|
+
const elapsed = Date.now() - sigtermAt;
|
|
91
|
+
expect(elapsed).toBeGreaterThanOrEqual(3000); // the bound was actually served
|
|
92
|
+
expect(elapsed).toBeLessThan(9000); // ...and it ended the drain, not the 60s request
|
|
93
|
+
await slow; // the held request errored (socket destroyed) — surfaced, not leaked
|
|
94
|
+
}, 30000);
|
|
95
|
+
|
|
96
|
+
it('SIGINT: fast exit 0 (dev ctrl-C)', async () => {
|
|
97
|
+
fixture = await startFixture({ drainDelayMs: 3000, drainTimeoutMs: 10000 });
|
|
98
|
+
const sigintAt = Date.now();
|
|
99
|
+
fixture.child.kill('SIGINT');
|
|
100
|
+
const exit = await fixture.exited;
|
|
101
|
+
expect(exit).toEqual({ code: 0, signal: null });
|
|
102
|
+
expect(Date.now() - sigintAt).toBeLessThan(2000); // no drain delay on the fast path
|
|
103
|
+
}, 30000);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
async function startFixture(shutdown: { drainDelayMs: number; drainTimeoutMs: number }): Promise<Fixture> {
|
|
107
|
+
const port = await ephemeralPort();
|
|
108
|
+
// Scrub the env vars startServer reads (dev machines export some of these): the fixture's
|
|
109
|
+
// behavior must come from its own config only.
|
|
110
|
+
const env = { ...process.env };
|
|
111
|
+
delete env.SERVER_PORT;
|
|
112
|
+
delete env.DEVELOPMENT;
|
|
113
|
+
delete env.DISABLE_HOT_CLIENT_BUILDS;
|
|
114
|
+
delete env.HMR_PORT;
|
|
115
|
+
const child = spawn(process.execPath, [fixturePath], {
|
|
116
|
+
cwd: packageRoot,
|
|
117
|
+
env: {
|
|
118
|
+
...env,
|
|
119
|
+
FIXTURE_PORT: String(port),
|
|
120
|
+
FIXTURE_DRAIN_DELAY_MS: String(shutdown.drainDelayMs),
|
|
121
|
+
FIXTURE_DRAIN_TIMEOUT_MS: String(shutdown.drainTimeoutMs),
|
|
122
|
+
},
|
|
123
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
124
|
+
});
|
|
125
|
+
let output = '';
|
|
126
|
+
child.stdout!.on('data', (chunk) => (output += String(chunk)));
|
|
127
|
+
child.stderr!.on('data', (chunk) => (output += String(chunk)));
|
|
128
|
+
const exited = new Promise<{ code: number | null; signal: NodeJS.Signals | null }>((resolve) =>
|
|
129
|
+
child.once('exit', (code, signal) => resolve({ code, signal }))
|
|
130
|
+
);
|
|
131
|
+
const fixture: Fixture = {
|
|
132
|
+
child,
|
|
133
|
+
port,
|
|
134
|
+
stdout: () => output,
|
|
135
|
+
waitForMarker: async (marker: string, timeoutMs = 15000) => {
|
|
136
|
+
const deadline = Date.now() + timeoutMs;
|
|
137
|
+
while (!output.includes(marker)) {
|
|
138
|
+
if (Date.now() > deadline) {
|
|
139
|
+
throw new Error(`Timed out waiting for marker ${marker}; output so far:\n${output}`);
|
|
140
|
+
}
|
|
141
|
+
await sleep(50);
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
exited,
|
|
145
|
+
};
|
|
146
|
+
// Ready = the health check answers 200 (readiness through the front door, not log lines).
|
|
147
|
+
const deadline = Date.now() + 20000;
|
|
148
|
+
for (;;) {
|
|
149
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
150
|
+
throw new Error(`Fixture exited during boot; output:\n${output}`);
|
|
151
|
+
}
|
|
152
|
+
const result = await request(port, '/health-check').catch(() => undefined);
|
|
153
|
+
if (result?.status === 200) {
|
|
154
|
+
return fixture;
|
|
155
|
+
}
|
|
156
|
+
if (Date.now() > deadline) {
|
|
157
|
+
throw new Error(`Fixture never became ready; output:\n${output}`);
|
|
158
|
+
}
|
|
159
|
+
await sleep(100);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** One request on its OWN connection (agent: false — no keep-alive pooling), so listener
|
|
164
|
+
* refusal after close is observable instead of masked by a pooled connection. */
|
|
165
|
+
function request(port: number, requestPath: string): Promise<{ status: number; body: string }> {
|
|
166
|
+
return new Promise((resolve, reject) => {
|
|
167
|
+
const req = http.get({ host: '127.0.0.1', port, path: requestPath, agent: false }, (res) => {
|
|
168
|
+
let body = '';
|
|
169
|
+
res.on('data', (chunk) => (body += String(chunk)));
|
|
170
|
+
res.on('end', () => resolve({ status: res.statusCode ?? 0, body }));
|
|
171
|
+
res.on('error', reject);
|
|
172
|
+
});
|
|
173
|
+
req.on('error', reject);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async function ephemeralPort(): Promise<number> {
|
|
178
|
+
return new Promise((resolve, reject) => {
|
|
179
|
+
const probe = net.createServer();
|
|
180
|
+
probe.once('error', reject);
|
|
181
|
+
probe.listen(0, '127.0.0.1', () => {
|
|
182
|
+
const address = probe.address() as net.AddressInfo;
|
|
183
|
+
probe.close(() => resolve(address.port));
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function sleep(ms: number): Promise<void> {
|
|
189
|
+
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
190
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
+
"noEmitOnError": true,
|
|
3
4
|
"rootDir": "./",
|
|
4
5
|
"target": "es5",
|
|
5
6
|
"module": "commonjs",
|
|
@@ -14,5 +15,6 @@
|
|
|
14
15
|
"forceConsistentCasingInFileNames": true,
|
|
15
16
|
"resolveJsonModule": true,
|
|
16
17
|
"allowJs": true
|
|
17
|
-
}
|
|
18
|
+
},
|
|
19
|
+
"exclude": ["node_modules", "dist", "test", "jest.config.js"]
|
|
18
20
|
}
|
package/dist/jest.config.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jest.config.d.ts","sourceRoot":"","sources":["../jest.config.js"],"names":[],"mappings":""}
|
package/dist/jest.config.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
module.exports = {
|
|
3
|
-
roots: ['<rootDir>/test'],
|
|
4
|
-
transform: {
|
|
5
|
-
'^.+\\.tsx?$': 'ts-jest',
|
|
6
|
-
},
|
|
7
|
-
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
|
|
8
|
-
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
|
|
9
|
-
testEnvironment: 'node',
|
|
10
|
-
};
|
|
11
|
-
//# sourceMappingURL=jest.config.js.map
|
package/dist/jest.config.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jest.config.js","sourceRoot":"","sources":["../jest.config.js"],"names":[],"mappings":";AAAA,MAAM,CAAC,OAAO,GAAG;IACf,KAAK,EAAE,CAAC,gBAAgB,CAAC;IACzB,SAAS,EAAE;QACT,aAAa,EAAE,SAAS;KACzB;IACD,SAAS,EAAE,4CAA4C;IACvD,oBAAoB,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC;IAChE,eAAe,EAAE,MAAM;CACxB,CAAC"}
|