@naturalcycles/backend-lib 9.63.0 → 9.63.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.
@@ -32,7 +32,7 @@ export interface StartServerCfg extends DefaultAppCfg {
32
32
  */
33
33
  onShutdown?: () => Promise<void>;
34
34
  /**
35
- * @default 3000
35
+ * @default 8_000
36
36
  */
37
37
  forceShutdownTimeout?: number;
38
38
  sentryService?: SentrySharedService;
@@ -45,8 +45,13 @@ export class BackendServer {
45
45
  resolve(server);
46
46
  });
47
47
  });
48
- // This is to fix GCP LoadBalancer race condition
49
- this.server.keepAliveTimeout = 600 * 1000; // 10 minutes
48
+ // This is to fix GCP LoadBalancer race condition:
49
+ // GCLB's backend keep-alive timeout is fixed at 600s, and the backend must use
50
+ // a strictly higher value, otherwise the server can close an idle connection at the
51
+ // same moment GCLB reuses it, resulting in intermittent 502s.
52
+ // https://cloud.google.com/load-balancing/docs/https#timeouts_and_retries
53
+ this.server.keepAliveTimeout = 620 * 1000; // slightly above GCLB's 600s
54
+ this.server.headersTimeout = 630 * 1000; // conventionally kept above keepAliveTimeout
50
55
  let address = `http://localhost:${port}`; // default
51
56
  const addr = this.server.address();
52
57
  if (addr) {
@@ -77,7 +82,7 @@ export class BackendServer {
77
82
  const shutdownTimeout = setTimeout(() => {
78
83
  console.log(boldGrey('Forceful shutdown after timeout'));
79
84
  process.exit(0);
80
- }, this.cfg.forceShutdownTimeout ?? 10_000);
85
+ }, this.cfg.forceShutdownTimeout ?? 8000);
81
86
  try {
82
87
  await Promise.all([
83
88
  this.server && new Promise(r => this.server.close(r)),
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@naturalcycles/backend-lib",
3
3
  "type": "module",
4
- "version": "9.63.0",
4
+ "version": "9.63.1",
5
5
  "dependencies": {
6
6
  "@naturalcycles/db-lib": "^10",
7
7
  "@naturalcycles/js-lib": "^15",
8
8
  "@naturalcycles/nodejs-lib": "^15",
9
9
  "@types/body-parser": "^1",
10
- "@types/compressible": "^2",
11
10
  "@types/cookie-parser": "^1",
12
11
  "@types/cors": "^2",
13
12
  "@types/express": "^5",
13
+ "@types/compressible": "^2",
14
14
  "@types/on-finished": "^2",
15
15
  "@types/on-headers": "^1",
16
16
  "@types/vary": "^1",
@@ -20,8 +20,8 @@
20
20
  "express": "^5",
21
21
  "helmet": "^8",
22
22
  "negotiator": "^1",
23
- "on-finished": "^2",
24
23
  "on-headers": "^1",
24
+ "on-finished": "^2",
25
25
  "tslib": "^2",
26
26
  "vary": "^1"
27
27
  },
@@ -43,9 +43,9 @@
43
43
  },
44
44
  "devDependencies": {
45
45
  "@sentry/node-core": "^10",
46
- "fastify": "^5",
47
46
  "typescript": "rc",
48
- "@naturalcycles/dev-lib": "20.50.0"
47
+ "fastify": "^5",
48
+ "@naturalcycles/dev-lib": "0.0.0"
49
49
  },
50
50
  "exports": {
51
51
  ".": "./dist/index.js",
@@ -53,8 +53,13 @@ export class BackendServer {
53
53
  })
54
54
  })
55
55
 
56
- // This is to fix GCP LoadBalancer race condition
57
- this.server.keepAliveTimeout = 600 * 1000 // 10 minutes
56
+ // This is to fix GCP LoadBalancer race condition:
57
+ // GCLB's backend keep-alive timeout is fixed at 600s, and the backend must use
58
+ // a strictly higher value, otherwise the server can close an idle connection at the
59
+ // same moment GCLB reuses it, resulting in intermittent 502s.
60
+ // https://cloud.google.com/load-balancing/docs/https#timeouts_and_retries
61
+ this.server.keepAliveTimeout = 620 * 1000 // slightly above GCLB's 600s
62
+ this.server.headersTimeout = 630 * 1000 // conventionally kept above keepAliveTimeout
58
63
 
59
64
  let address = `http://localhost:${port}` // default
60
65
 
@@ -97,7 +102,7 @@ export class BackendServer {
97
102
  const shutdownTimeout = setTimeout(() => {
98
103
  console.log(boldGrey('Forceful shutdown after timeout'))
99
104
  process.exit(0)
100
- }, this.cfg.forceShutdownTimeout ?? 10_000)
105
+ }, this.cfg.forceShutdownTimeout ?? 8000)
101
106
 
102
107
  try {
103
108
  await Promise.all([
@@ -146,7 +151,7 @@ export interface StartServerCfg extends DefaultAppCfg {
146
151
  onShutdown?: () => Promise<void>
147
152
 
148
153
  /**
149
- * @default 3000
154
+ * @default 8_000
150
155
  */
151
156
  forceShutdownTimeout?: number
152
157