@tramvai/module-server 2.70.1 → 2.72.0
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/lib/browser.js +2 -31
- package/lib/modules/debugRequests.es.js +143 -0
- package/lib/modules/debugRequests.js +151 -0
- package/lib/modules/dependenciesVersion.es.js +47 -0
- package/lib/modules/dependenciesVersion.js +49 -0
- package/lib/modules/gracefulShutdown.es.js +104 -0
- package/lib/modules/gracefulShutdown.js +106 -0
- package/lib/modules/keepAlive.es.js +47 -0
- package/lib/modules/keepAlive.js +49 -0
- package/lib/modules/papi/api/index.es.js +80 -0
- package/lib/modules/papi/api/index.js +88 -0
- package/lib/modules/papi/papi.browser.browser.js +13 -0
- package/lib/modules/papi/papi.browser.es.js +13 -0
- package/lib/modules/papi/papi.browser.js +15 -0
- package/lib/modules/papi/papi.es.js +111 -0
- package/lib/modules/papi/papi.js +118 -0
- package/lib/modules/papi/server/executor.es.js +39 -0
- package/lib/modules/papi/server/executor.js +43 -0
- package/lib/modules/papi/server/fileApi.es.js +44 -0
- package/lib/modules/papi/server/fileApi.js +52 -0
- package/lib/modules/papi/shared.browser.js +25 -0
- package/lib/modules/papi/shared.es.js +25 -0
- package/lib/modules/papi/shared.js +29 -0
- package/lib/modules/proxy.es.js +65 -0
- package/lib/modules/proxy.js +73 -0
- package/lib/modules/serverTiming.es.js +30 -0
- package/lib/modules/serverTiming.js +34 -0
- package/lib/modules/statics.es.js +48 -0
- package/lib/modules/statics.js +54 -0
- package/lib/modules/utilityServer.es.js +99 -0
- package/lib/modules/utilityServer.js +101 -0
- package/lib/modules/utils/require.es.js +11 -0
- package/lib/modules/utils/require.js +16 -0
- package/lib/modules/utils/tramvaiDepsFilter.es.js +8 -0
- package/lib/modules/utils/tramvaiDepsFilter.js +16 -0
- package/lib/server/error.es.js +54 -0
- package/lib/server/error.js +62 -0
- package/lib/server/server.es.js +17 -0
- package/lib/server/server.js +26 -0
- package/lib/server/static.es.js +34 -0
- package/lib/server/static.js +44 -0
- package/lib/server/webApp.es.js +103 -0
- package/lib/server/webApp.js +113 -0
- package/lib/server/xHeaders.es.js +21 -0
- package/lib/server/xHeaders.js +30 -0
- package/lib/server.es.js +24 -1035
- package/lib/server.js +29 -1055
- package/package.json +19 -20
package/lib/browser.js
CHANGED
|
@@ -1,38 +1,9 @@
|
|
|
1
1
|
import { __decorate } from 'tslib';
|
|
2
|
-
import {
|
|
2
|
+
import { Module } from '@tramvai/core';
|
|
3
3
|
import { MetricsModule } from '@tramvai/module-metrics';
|
|
4
|
-
import {
|
|
4
|
+
import { BrowserPapiModule } from './modules/papi/papi.browser.browser.js';
|
|
5
5
|
export * from '@tramvai/tokens-server';
|
|
6
6
|
|
|
7
|
-
const sharedProviders = [
|
|
8
|
-
{
|
|
9
|
-
provide: SERVER_MODULE_PAPI_PUBLIC_URL,
|
|
10
|
-
useFactory: ({ appInfo }) => {
|
|
11
|
-
return `/${appInfo.appName}/papi`;
|
|
12
|
-
},
|
|
13
|
-
deps: {
|
|
14
|
-
appInfo: APP_INFO_TOKEN,
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
provide: SERVER_MODULE_PAPI_PRIVATE_URL,
|
|
19
|
-
useFactory: ({ appInfo }) => {
|
|
20
|
-
return `/${appInfo.appName}/private/papi`;
|
|
21
|
-
},
|
|
22
|
-
deps: {
|
|
23
|
-
appInfo: APP_INFO_TOKEN,
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
let BrowserPapiModule = class BrowserPapiModule {
|
|
29
|
-
};
|
|
30
|
-
BrowserPapiModule = __decorate([
|
|
31
|
-
Module({
|
|
32
|
-
providers: [...sharedProviders],
|
|
33
|
-
})
|
|
34
|
-
], BrowserPapiModule);
|
|
35
|
-
|
|
36
7
|
let ServerModule = class ServerModule {
|
|
37
8
|
};
|
|
38
9
|
ServerModule = __decorate([
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
|
+
import { LOGGER_TOKEN } from '@tramvai/tokens-common';
|
|
3
|
+
import { createPapiMethod } from '@tramvai/papi';
|
|
4
|
+
import { SERVER_MODULE_PAPI_PRIVATE_ROUTE } from '@tramvai/tokens-server';
|
|
5
|
+
import { Module, Scope, commandLineListTokens } from '@tramvai/core';
|
|
6
|
+
import { parse } from '@tinkoff/url';
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
import monkeypatch from '@tinkoff/monkeypatch';
|
|
9
|
+
import http from 'http';
|
|
10
|
+
import https from 'https';
|
|
11
|
+
|
|
12
|
+
class Interceptor {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.intercepted = false;
|
|
15
|
+
this.delay = 0;
|
|
16
|
+
}
|
|
17
|
+
setIntercept(intercept) {
|
|
18
|
+
this.intercepted = intercept;
|
|
19
|
+
}
|
|
20
|
+
setDelay(delay) {
|
|
21
|
+
this.intercepted = true;
|
|
22
|
+
this.delay = delay;
|
|
23
|
+
}
|
|
24
|
+
clear() {
|
|
25
|
+
this.intercepted = false;
|
|
26
|
+
this.delay = 0;
|
|
27
|
+
}
|
|
28
|
+
getStatus() {
|
|
29
|
+
return {
|
|
30
|
+
intercepted: this.intercepted,
|
|
31
|
+
delay: this.delay,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const INTERCEPTOR_TOKEN = 'debugRequestsInterceptor';
|
|
36
|
+
let DebugHttpRequestsModule = class DebugHttpRequestsModule {
|
|
37
|
+
};
|
|
38
|
+
DebugHttpRequestsModule = __decorate([
|
|
39
|
+
Module({
|
|
40
|
+
providers: [
|
|
41
|
+
{
|
|
42
|
+
provide: INTERCEPTOR_TOKEN,
|
|
43
|
+
useClass: Interceptor,
|
|
44
|
+
scope: Scope.SINGLETON,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
provide: commandLineListTokens.init,
|
|
48
|
+
multi: true,
|
|
49
|
+
useFactory: ({ logger, interceptor }) => {
|
|
50
|
+
const log = logger('server:node-debug:request');
|
|
51
|
+
return function debugHttp() {
|
|
52
|
+
const handler = (request, options, cb) => {
|
|
53
|
+
const parsed = typeof options === 'string' ? parse(options) : options;
|
|
54
|
+
const wasHandled = typeof cb === 'function';
|
|
55
|
+
return request(options, cb)
|
|
56
|
+
.on('response', (response) => {
|
|
57
|
+
interceptor.intercepted &&
|
|
58
|
+
monkeypatch({
|
|
59
|
+
obj: response,
|
|
60
|
+
method: 'emit',
|
|
61
|
+
handler: (emit, event, ...args) => {
|
|
62
|
+
if (event === 'end') {
|
|
63
|
+
setTimeout(() => {
|
|
64
|
+
emit(event, ...args);
|
|
65
|
+
}, interceptor.delay);
|
|
66
|
+
return !!response.listenerCount(event);
|
|
67
|
+
}
|
|
68
|
+
return emit(event, ...args);
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
})
|
|
72
|
+
.on('response', (response) => {
|
|
73
|
+
// Workaround for res._dump in Node.JS http client
|
|
74
|
+
// https://github.com/nodejs/node/blob/20285ad17755187ece16b8a5effeaa87f5407da2/lib/_http_client.js#L421-L427
|
|
75
|
+
if (!wasHandled && EventEmitter.listenerCount(response.req, 'response') === 0) {
|
|
76
|
+
response.resume();
|
|
77
|
+
}
|
|
78
|
+
log.debug(`${response.statusCode}
|
|
79
|
+
${parsed.href || `${parsed.protocol}//${parsed.hostname}${parsed.path}`}
|
|
80
|
+
`);
|
|
81
|
+
})
|
|
82
|
+
.on('error', (error) => {
|
|
83
|
+
log.error({
|
|
84
|
+
event: 'request-failed',
|
|
85
|
+
error,
|
|
86
|
+
url: parsed.href || options,
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
monkeypatch({ obj: http, method: 'request', handler });
|
|
91
|
+
monkeypatch({ obj: https, method: 'request', handler });
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
deps: {
|
|
95
|
+
logger: LOGGER_TOKEN,
|
|
96
|
+
interceptor: INTERCEPTOR_TOKEN,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
provide: SERVER_MODULE_PAPI_PRIVATE_ROUTE,
|
|
101
|
+
multi: true,
|
|
102
|
+
useFactory: ({ interceptor }) => {
|
|
103
|
+
return createPapiMethod({
|
|
104
|
+
method: 'post',
|
|
105
|
+
path: '/debug-http-request',
|
|
106
|
+
async handler({ body }) {
|
|
107
|
+
const { delay = 10000 } = body;
|
|
108
|
+
if (delay) {
|
|
109
|
+
interceptor.setDelay(delay);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
interceptor.setIntercept(true);
|
|
113
|
+
}
|
|
114
|
+
return interceptor.getStatus();
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
deps: {
|
|
119
|
+
interceptor: INTERCEPTOR_TOKEN,
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
provide: SERVER_MODULE_PAPI_PRIVATE_ROUTE,
|
|
124
|
+
multi: true,
|
|
125
|
+
useFactory: ({ interceptor }) => {
|
|
126
|
+
return createPapiMethod({
|
|
127
|
+
method: 'delete',
|
|
128
|
+
path: '/debug-http-request',
|
|
129
|
+
async handler() {
|
|
130
|
+
interceptor.clear();
|
|
131
|
+
return interceptor.getStatus();
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
deps: {
|
|
136
|
+
interceptor: INTERCEPTOR_TOKEN,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
})
|
|
141
|
+
], DebugHttpRequestsModule);
|
|
142
|
+
|
|
143
|
+
export { DebugHttpRequestsModule };
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tslib = require('tslib');
|
|
6
|
+
var tokensCommon = require('@tramvai/tokens-common');
|
|
7
|
+
var papi = require('@tramvai/papi');
|
|
8
|
+
var tokensServer = require('@tramvai/tokens-server');
|
|
9
|
+
var core = require('@tramvai/core');
|
|
10
|
+
var url = require('@tinkoff/url');
|
|
11
|
+
var EventEmitter = require('events');
|
|
12
|
+
var monkeypatch = require('@tinkoff/monkeypatch');
|
|
13
|
+
var http = require('http');
|
|
14
|
+
var https = require('https');
|
|
15
|
+
|
|
16
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
17
|
+
|
|
18
|
+
var monkeypatch__default = /*#__PURE__*/_interopDefaultLegacy(monkeypatch);
|
|
19
|
+
var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
|
|
20
|
+
var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
|
|
21
|
+
|
|
22
|
+
class Interceptor {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.intercepted = false;
|
|
25
|
+
this.delay = 0;
|
|
26
|
+
}
|
|
27
|
+
setIntercept(intercept) {
|
|
28
|
+
this.intercepted = intercept;
|
|
29
|
+
}
|
|
30
|
+
setDelay(delay) {
|
|
31
|
+
this.intercepted = true;
|
|
32
|
+
this.delay = delay;
|
|
33
|
+
}
|
|
34
|
+
clear() {
|
|
35
|
+
this.intercepted = false;
|
|
36
|
+
this.delay = 0;
|
|
37
|
+
}
|
|
38
|
+
getStatus() {
|
|
39
|
+
return {
|
|
40
|
+
intercepted: this.intercepted,
|
|
41
|
+
delay: this.delay,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const INTERCEPTOR_TOKEN = 'debugRequestsInterceptor';
|
|
46
|
+
exports.DebugHttpRequestsModule = class DebugHttpRequestsModule {
|
|
47
|
+
};
|
|
48
|
+
exports.DebugHttpRequestsModule = tslib.__decorate([
|
|
49
|
+
core.Module({
|
|
50
|
+
providers: [
|
|
51
|
+
{
|
|
52
|
+
provide: INTERCEPTOR_TOKEN,
|
|
53
|
+
useClass: Interceptor,
|
|
54
|
+
scope: core.Scope.SINGLETON,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
provide: core.commandLineListTokens.init,
|
|
58
|
+
multi: true,
|
|
59
|
+
useFactory: ({ logger, interceptor }) => {
|
|
60
|
+
const log = logger('server:node-debug:request');
|
|
61
|
+
return function debugHttp() {
|
|
62
|
+
const handler = (request, options, cb) => {
|
|
63
|
+
const parsed = typeof options === 'string' ? url.parse(options) : options;
|
|
64
|
+
const wasHandled = typeof cb === 'function';
|
|
65
|
+
return request(options, cb)
|
|
66
|
+
.on('response', (response) => {
|
|
67
|
+
interceptor.intercepted &&
|
|
68
|
+
monkeypatch__default["default"]({
|
|
69
|
+
obj: response,
|
|
70
|
+
method: 'emit',
|
|
71
|
+
handler: (emit, event, ...args) => {
|
|
72
|
+
if (event === 'end') {
|
|
73
|
+
setTimeout(() => {
|
|
74
|
+
emit(event, ...args);
|
|
75
|
+
}, interceptor.delay);
|
|
76
|
+
return !!response.listenerCount(event);
|
|
77
|
+
}
|
|
78
|
+
return emit(event, ...args);
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
})
|
|
82
|
+
.on('response', (response) => {
|
|
83
|
+
// Workaround for res._dump in Node.JS http client
|
|
84
|
+
// https://github.com/nodejs/node/blob/20285ad17755187ece16b8a5effeaa87f5407da2/lib/_http_client.js#L421-L427
|
|
85
|
+
if (!wasHandled && EventEmitter.EventEmitter.listenerCount(response.req, 'response') === 0) {
|
|
86
|
+
response.resume();
|
|
87
|
+
}
|
|
88
|
+
log.debug(`${response.statusCode}
|
|
89
|
+
${parsed.href || `${parsed.protocol}//${parsed.hostname}${parsed.path}`}
|
|
90
|
+
`);
|
|
91
|
+
})
|
|
92
|
+
.on('error', (error) => {
|
|
93
|
+
log.error({
|
|
94
|
+
event: 'request-failed',
|
|
95
|
+
error,
|
|
96
|
+
url: parsed.href || options,
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
monkeypatch__default["default"]({ obj: http__default["default"], method: 'request', handler });
|
|
101
|
+
monkeypatch__default["default"]({ obj: https__default["default"], method: 'request', handler });
|
|
102
|
+
};
|
|
103
|
+
},
|
|
104
|
+
deps: {
|
|
105
|
+
logger: tokensCommon.LOGGER_TOKEN,
|
|
106
|
+
interceptor: INTERCEPTOR_TOKEN,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
provide: tokensServer.SERVER_MODULE_PAPI_PRIVATE_ROUTE,
|
|
111
|
+
multi: true,
|
|
112
|
+
useFactory: ({ interceptor }) => {
|
|
113
|
+
return papi.createPapiMethod({
|
|
114
|
+
method: 'post',
|
|
115
|
+
path: '/debug-http-request',
|
|
116
|
+
async handler({ body }) {
|
|
117
|
+
const { delay = 10000 } = body;
|
|
118
|
+
if (delay) {
|
|
119
|
+
interceptor.setDelay(delay);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
interceptor.setIntercept(true);
|
|
123
|
+
}
|
|
124
|
+
return interceptor.getStatus();
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
deps: {
|
|
129
|
+
interceptor: INTERCEPTOR_TOKEN,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
provide: tokensServer.SERVER_MODULE_PAPI_PRIVATE_ROUTE,
|
|
134
|
+
multi: true,
|
|
135
|
+
useFactory: ({ interceptor }) => {
|
|
136
|
+
return papi.createPapiMethod({
|
|
137
|
+
method: 'delete',
|
|
138
|
+
path: '/debug-http-request',
|
|
139
|
+
async handler() {
|
|
140
|
+
interceptor.clear();
|
|
141
|
+
return interceptor.getStatus();
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
deps: {
|
|
146
|
+
interceptor: INTERCEPTOR_TOKEN,
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
})
|
|
151
|
+
], exports.DebugHttpRequestsModule);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
import { Module } from '@tramvai/core';
|
|
4
|
+
import { createPapiMethod } from '@tramvai/papi';
|
|
5
|
+
import { SERVER_MODULE_PAPI_PRIVATE_ROUTE, DEPENDENCIES_VERSION_FILTER_TOKEN } from '@tramvai/tokens-server';
|
|
6
|
+
import { safeNodeRequire } from './utils/require.es.js';
|
|
7
|
+
import { tramvaiDepsFilter } from './utils/tramvaiDepsFilter.es.js';
|
|
8
|
+
|
|
9
|
+
let packageJson = {};
|
|
10
|
+
try {
|
|
11
|
+
// eslint-disable-next-line import/no-unresolved
|
|
12
|
+
packageJson = require('../../../../package.json');
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
packageJson = safeNodeRequire(resolve(process.cwd(), 'package.json'));
|
|
16
|
+
}
|
|
17
|
+
let DependenciesVersionModule = class DependenciesVersionModule {
|
|
18
|
+
};
|
|
19
|
+
DependenciesVersionModule = __decorate([
|
|
20
|
+
Module({
|
|
21
|
+
providers: [
|
|
22
|
+
{
|
|
23
|
+
provide: SERVER_MODULE_PAPI_PRIVATE_ROUTE,
|
|
24
|
+
multi: true,
|
|
25
|
+
useFactory: ({ depsFilter }) => {
|
|
26
|
+
const { dependencies = [] } = packageJson !== null && packageJson !== void 0 ? packageJson : {};
|
|
27
|
+
return createPapiMethod({
|
|
28
|
+
path: '/dependenciesVersion',
|
|
29
|
+
method: 'get',
|
|
30
|
+
handler: async () => {
|
|
31
|
+
return depsFilter(dependencies);
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
deps: {
|
|
36
|
+
depsFilter: DEPENDENCIES_VERSION_FILTER_TOKEN,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
provide: DEPENDENCIES_VERSION_FILTER_TOKEN,
|
|
41
|
+
useValue: tramvaiDepsFilter,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
})
|
|
45
|
+
], DependenciesVersionModule);
|
|
46
|
+
|
|
47
|
+
export { DependenciesVersionModule };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tslib = require('tslib');
|
|
6
|
+
var path = require('path');
|
|
7
|
+
var core = require('@tramvai/core');
|
|
8
|
+
var papi = require('@tramvai/papi');
|
|
9
|
+
var tokensServer = require('@tramvai/tokens-server');
|
|
10
|
+
var require$1 = require('./utils/require.js');
|
|
11
|
+
var tramvaiDepsFilter = require('./utils/tramvaiDepsFilter.js');
|
|
12
|
+
|
|
13
|
+
let packageJson = {};
|
|
14
|
+
try {
|
|
15
|
+
// eslint-disable-next-line import/no-unresolved
|
|
16
|
+
packageJson = require('../../../../package.json');
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
packageJson = require$1.safeNodeRequire(path.resolve(process.cwd(), 'package.json'));
|
|
20
|
+
}
|
|
21
|
+
exports.DependenciesVersionModule = class DependenciesVersionModule {
|
|
22
|
+
};
|
|
23
|
+
exports.DependenciesVersionModule = tslib.__decorate([
|
|
24
|
+
core.Module({
|
|
25
|
+
providers: [
|
|
26
|
+
{
|
|
27
|
+
provide: tokensServer.SERVER_MODULE_PAPI_PRIVATE_ROUTE,
|
|
28
|
+
multi: true,
|
|
29
|
+
useFactory: ({ depsFilter }) => {
|
|
30
|
+
const { dependencies = [] } = packageJson !== null && packageJson !== void 0 ? packageJson : {};
|
|
31
|
+
return papi.createPapiMethod({
|
|
32
|
+
path: '/dependenciesVersion',
|
|
33
|
+
method: 'get',
|
|
34
|
+
handler: async () => {
|
|
35
|
+
return depsFilter(dependencies);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
deps: {
|
|
40
|
+
depsFilter: tokensServer.DEPENDENCIES_VERSION_FILTER_TOKEN,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
provide: tokensServer.DEPENDENCIES_VERSION_FILTER_TOKEN,
|
|
45
|
+
useValue: tramvaiDepsFilter.tramvaiDepsFilter,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
})
|
|
49
|
+
], exports.DependenciesVersionModule);
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
|
+
import { createTerminus } from '@tinkoff/terminus';
|
|
3
|
+
import { SERVER_TOKEN, LIVENESS_PATH_TOKEN, READINESS_PATH_TOKEN, READINESS_PROBE_TOKEN, LIVENESS_PROBE_TOKEN, UTILITY_SERVER_PATHS } from '@tramvai/tokens-server';
|
|
4
|
+
import { WEB_FASTIFY_APP_BEFORE_INIT_TOKEN, UTILITY_WEB_FASTIFY_APP_TOKEN } from '@tramvai/tokens-server-private';
|
|
5
|
+
import { LOGGER_TOKEN } from '@tramvai/tokens-common';
|
|
6
|
+
import { Module, provide, COMMAND_LINE_RUNNER_TOKEN } from '@tramvai/core';
|
|
7
|
+
|
|
8
|
+
const GRACEFUL_SHUTDOWN_TIMEOUT = 25000;
|
|
9
|
+
const GRACEFUL_READINESS_TIMEOUT = 5000;
|
|
10
|
+
const noopCheck = () => { };
|
|
11
|
+
let ServerGracefulShutdownModule = class ServerGracefulShutdownModule {
|
|
12
|
+
};
|
|
13
|
+
ServerGracefulShutdownModule = __decorate([
|
|
14
|
+
Module({
|
|
15
|
+
providers: [
|
|
16
|
+
provide({
|
|
17
|
+
provide: WEB_FASTIFY_APP_BEFORE_INIT_TOKEN,
|
|
18
|
+
multi: true,
|
|
19
|
+
useFactory: ({ app, server, logger, commandLineRunner, livenessPath, readinessPath, livenessProbe, readinessProbe, }) => {
|
|
20
|
+
const log = logger('server');
|
|
21
|
+
return function serverListen() {
|
|
22
|
+
createTerminus(server, app, {
|
|
23
|
+
signal: 'SIGTERM',
|
|
24
|
+
timeout: GRACEFUL_SHUTDOWN_TIMEOUT,
|
|
25
|
+
logger: (msg, error) => {
|
|
26
|
+
log.error({
|
|
27
|
+
event: 'terminus',
|
|
28
|
+
message: msg,
|
|
29
|
+
error,
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
// https://github.com/godaddy/terminus#how-to-set-terminus-up-with-kubernetes
|
|
33
|
+
beforeShutdown: () => {
|
|
34
|
+
log.warn({
|
|
35
|
+
event: 'terminus-wait',
|
|
36
|
+
message: 'wait for other tasks before shutdown',
|
|
37
|
+
});
|
|
38
|
+
return new Promise((resolve) => setTimeout(resolve, GRACEFUL_READINESS_TIMEOUT));
|
|
39
|
+
},
|
|
40
|
+
onSignal: () => {
|
|
41
|
+
log.warn({
|
|
42
|
+
event: 'terminus-run-command',
|
|
43
|
+
message: 'run commandLineRunner close line',
|
|
44
|
+
});
|
|
45
|
+
commandLineRunner.run('server', 'close');
|
|
46
|
+
},
|
|
47
|
+
onShutdown: () => {
|
|
48
|
+
log.warn({
|
|
49
|
+
event: 'terminus-exit',
|
|
50
|
+
message: 'calling process.exit',
|
|
51
|
+
});
|
|
52
|
+
process.exit();
|
|
53
|
+
},
|
|
54
|
+
healthChecks: {
|
|
55
|
+
[livenessPath]: livenessProbe || noopCheck,
|
|
56
|
+
[readinessPath]: readinessProbe || noopCheck,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
deps: {
|
|
62
|
+
app: UTILITY_WEB_FASTIFY_APP_TOKEN,
|
|
63
|
+
server: SERVER_TOKEN,
|
|
64
|
+
logger: LOGGER_TOKEN,
|
|
65
|
+
commandLineRunner: COMMAND_LINE_RUNNER_TOKEN,
|
|
66
|
+
livenessPath: LIVENESS_PATH_TOKEN,
|
|
67
|
+
readinessPath: READINESS_PATH_TOKEN,
|
|
68
|
+
readinessProbe: { token: READINESS_PROBE_TOKEN, optional: true },
|
|
69
|
+
livenessProbe: { token: LIVENESS_PROBE_TOKEN, optional: true },
|
|
70
|
+
},
|
|
71
|
+
}),
|
|
72
|
+
provide({
|
|
73
|
+
provide: LIVENESS_PATH_TOKEN,
|
|
74
|
+
useValue: '/healthz',
|
|
75
|
+
}),
|
|
76
|
+
provide({
|
|
77
|
+
provide: READINESS_PATH_TOKEN,
|
|
78
|
+
useValue: '/readyz',
|
|
79
|
+
}),
|
|
80
|
+
provide({
|
|
81
|
+
provide: UTILITY_SERVER_PATHS,
|
|
82
|
+
useFactory: ({ livenessPath }) => {
|
|
83
|
+
return livenessPath;
|
|
84
|
+
},
|
|
85
|
+
multi: true,
|
|
86
|
+
deps: {
|
|
87
|
+
livenessPath: LIVENESS_PATH_TOKEN,
|
|
88
|
+
},
|
|
89
|
+
}),
|
|
90
|
+
provide({
|
|
91
|
+
provide: UTILITY_SERVER_PATHS,
|
|
92
|
+
useFactory: ({ readinessPath }) => {
|
|
93
|
+
return readinessPath;
|
|
94
|
+
},
|
|
95
|
+
multi: true,
|
|
96
|
+
deps: {
|
|
97
|
+
readinessPath: READINESS_PATH_TOKEN,
|
|
98
|
+
},
|
|
99
|
+
}),
|
|
100
|
+
],
|
|
101
|
+
})
|
|
102
|
+
], ServerGracefulShutdownModule);
|
|
103
|
+
|
|
104
|
+
export { ServerGracefulShutdownModule };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tslib = require('tslib');
|
|
6
|
+
var terminus = require('@tinkoff/terminus');
|
|
7
|
+
var tokensServer = require('@tramvai/tokens-server');
|
|
8
|
+
var tokensServerPrivate = require('@tramvai/tokens-server-private');
|
|
9
|
+
var tokensCommon = require('@tramvai/tokens-common');
|
|
10
|
+
var core = require('@tramvai/core');
|
|
11
|
+
|
|
12
|
+
const GRACEFUL_SHUTDOWN_TIMEOUT = 25000;
|
|
13
|
+
const GRACEFUL_READINESS_TIMEOUT = 5000;
|
|
14
|
+
const noopCheck = () => { };
|
|
15
|
+
exports.ServerGracefulShutdownModule = class ServerGracefulShutdownModule {
|
|
16
|
+
};
|
|
17
|
+
exports.ServerGracefulShutdownModule = tslib.__decorate([
|
|
18
|
+
core.Module({
|
|
19
|
+
providers: [
|
|
20
|
+
core.provide({
|
|
21
|
+
provide: tokensServerPrivate.WEB_FASTIFY_APP_BEFORE_INIT_TOKEN,
|
|
22
|
+
multi: true,
|
|
23
|
+
useFactory: ({ app, server, logger, commandLineRunner, livenessPath, readinessPath, livenessProbe, readinessProbe, }) => {
|
|
24
|
+
const log = logger('server');
|
|
25
|
+
return function serverListen() {
|
|
26
|
+
terminus.createTerminus(server, app, {
|
|
27
|
+
signal: 'SIGTERM',
|
|
28
|
+
timeout: GRACEFUL_SHUTDOWN_TIMEOUT,
|
|
29
|
+
logger: (msg, error) => {
|
|
30
|
+
log.error({
|
|
31
|
+
event: 'terminus',
|
|
32
|
+
message: msg,
|
|
33
|
+
error,
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
// https://github.com/godaddy/terminus#how-to-set-terminus-up-with-kubernetes
|
|
37
|
+
beforeShutdown: () => {
|
|
38
|
+
log.warn({
|
|
39
|
+
event: 'terminus-wait',
|
|
40
|
+
message: 'wait for other tasks before shutdown',
|
|
41
|
+
});
|
|
42
|
+
return new Promise((resolve) => setTimeout(resolve, GRACEFUL_READINESS_TIMEOUT));
|
|
43
|
+
},
|
|
44
|
+
onSignal: () => {
|
|
45
|
+
log.warn({
|
|
46
|
+
event: 'terminus-run-command',
|
|
47
|
+
message: 'run commandLineRunner close line',
|
|
48
|
+
});
|
|
49
|
+
commandLineRunner.run('server', 'close');
|
|
50
|
+
},
|
|
51
|
+
onShutdown: () => {
|
|
52
|
+
log.warn({
|
|
53
|
+
event: 'terminus-exit',
|
|
54
|
+
message: 'calling process.exit',
|
|
55
|
+
});
|
|
56
|
+
process.exit();
|
|
57
|
+
},
|
|
58
|
+
healthChecks: {
|
|
59
|
+
[livenessPath]: livenessProbe || noopCheck,
|
|
60
|
+
[readinessPath]: readinessProbe || noopCheck,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
deps: {
|
|
66
|
+
app: tokensServerPrivate.UTILITY_WEB_FASTIFY_APP_TOKEN,
|
|
67
|
+
server: tokensServer.SERVER_TOKEN,
|
|
68
|
+
logger: tokensCommon.LOGGER_TOKEN,
|
|
69
|
+
commandLineRunner: core.COMMAND_LINE_RUNNER_TOKEN,
|
|
70
|
+
livenessPath: tokensServer.LIVENESS_PATH_TOKEN,
|
|
71
|
+
readinessPath: tokensServer.READINESS_PATH_TOKEN,
|
|
72
|
+
readinessProbe: { token: tokensServer.READINESS_PROBE_TOKEN, optional: true },
|
|
73
|
+
livenessProbe: { token: tokensServer.LIVENESS_PROBE_TOKEN, optional: true },
|
|
74
|
+
},
|
|
75
|
+
}),
|
|
76
|
+
core.provide({
|
|
77
|
+
provide: tokensServer.LIVENESS_PATH_TOKEN,
|
|
78
|
+
useValue: '/healthz',
|
|
79
|
+
}),
|
|
80
|
+
core.provide({
|
|
81
|
+
provide: tokensServer.READINESS_PATH_TOKEN,
|
|
82
|
+
useValue: '/readyz',
|
|
83
|
+
}),
|
|
84
|
+
core.provide({
|
|
85
|
+
provide: tokensServer.UTILITY_SERVER_PATHS,
|
|
86
|
+
useFactory: ({ livenessPath }) => {
|
|
87
|
+
return livenessPath;
|
|
88
|
+
},
|
|
89
|
+
multi: true,
|
|
90
|
+
deps: {
|
|
91
|
+
livenessPath: tokensServer.LIVENESS_PATH_TOKEN,
|
|
92
|
+
},
|
|
93
|
+
}),
|
|
94
|
+
core.provide({
|
|
95
|
+
provide: tokensServer.UTILITY_SERVER_PATHS,
|
|
96
|
+
useFactory: ({ readinessPath }) => {
|
|
97
|
+
return readinessPath;
|
|
98
|
+
},
|
|
99
|
+
multi: true,
|
|
100
|
+
deps: {
|
|
101
|
+
readinessPath: tokensServer.READINESS_PATH_TOKEN,
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
],
|
|
105
|
+
})
|
|
106
|
+
], exports.ServerGracefulShutdownModule);
|