@nsshunt/stsappframework 3.1.236 → 3.1.237
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/dist/stsappframework.mjs +1979 -0
- package/dist/stsappframework.mjs.map +1 -0
- package/dist/stsappframework.umd.js +1954 -0
- package/dist/stsappframework.umd.js.map +1 -0
- package/package.json +21 -7
- package/.github/dependabot.yml +0 -13
- package/.github/workflows/npm-publish.yml +0 -46
- package/.gitignore copy +0 -108
- package/build.sh +0 -36
- package/dist/index.js +0 -30
- package/eslint.config.mjs +0 -55
- package/jest/setEnvVars.js +0 -19
- package/keys/server.cert +0 -21
- package/keys/server.key +0 -28
- package/local-redis-stack.conf +0 -2
- package/run-grpc-client.sh +0 -2
- package/run-grpc-server.sh +0 -2
- package/run1.sh +0 -20
- package/run2.sh +0 -20
- package/run3.sh +0 -20
- package/runc1.sh +0 -19
- package/runc2.sh +0 -19
- package/runkafka.sh +0 -19
- package/runkafkaconsume01.sh +0 -21
- package/runkafkaconsume02.sh +0 -21
- package/runpromise.sh +0 -5
- package/runredis.sh +0 -5
- package/runredis1.sh +0 -4
- package/runredis2.sh +0 -24
- package/runredis3.sh +0 -4
- package/runtest1.sh +0 -19
- package/runtest2.sh +0 -19
- package/runtest_ipc_legacy.sh +0 -19
- package/runtest_ipcex.sh +0 -19
- package/runtest_redis.sh +0 -19
- package/runtest_ww.sh +0 -19
- package/src/commonTypes.ts +0 -374
- package/src/controller/stscontrollerbase.ts +0 -14
- package/src/controller/stslatencycontroller.ts +0 -26
- package/src/index.ts +0 -13
- package/src/logger/stsTransportLoggerWinston.ts +0 -24
- package/src/logger/stsTransportWinston.ts +0 -48
- package/src/middleware/serverNetworkMiddleware.ts +0 -243
- package/src/network.ts +0 -36
- package/src/process/masterprocessbase.ts +0 -674
- package/src/process/processbase.ts +0 -483
- package/src/process/serverprocessbase.ts +0 -455
- package/src/process/singleprocessbase.ts +0 -63
- package/src/process/workerprocessbase.ts +0 -224
- package/src/publishertransports/publishTransportUtils.ts +0 -53
- package/src/route/stslatencyroute.ts +0 -15
- package/src/route/stsrouterbase.ts +0 -21
- package/src/stsexpressserver.ts +0 -137
- package/src/validation/errors.ts +0 -6
- package/src/vitesttesting/appConfig.ts +0 -111
- package/src/vitesttesting/appSingleWSS.ts +0 -142
- package/src/vitesttesting/server.ts +0 -17
- package/src/vitesttesting/singleservertest.test.ts +0 -352
- package/src/vitesttesting/wsevents.ts +0 -44
- package/tsconfig.json +0 -42
- package/vite.config.ts +0 -19
|
@@ -1,455 +0,0 @@
|
|
|
1
|
-
/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
|
|
4
|
-
import { goptions } from '@nsshunt/stsconfig'
|
|
5
|
-
|
|
6
|
-
import fs from 'node:fs'
|
|
7
|
-
|
|
8
|
-
import { JSONObject, Sleep } from '@nsshunt/stsutils'
|
|
9
|
-
|
|
10
|
-
import { ProcessOptions, IServerProcessBase } from './../commonTypes'
|
|
11
|
-
import { ProcessBase } from './processbase';
|
|
12
|
-
|
|
13
|
-
import { register, Counter, collectDefaultMetrics, AggregatorRegistry } from 'prom-client'
|
|
14
|
-
|
|
15
|
-
import { createServer as createServerHttps } from 'node:https'
|
|
16
|
-
import { createServer } from 'node:http'
|
|
17
|
-
import tls from 'node:tls'
|
|
18
|
-
import net from 'node:net'
|
|
19
|
-
|
|
20
|
-
import { Server, ServerOptions } from "socket.io";
|
|
21
|
-
import { STSExpressServer } from './../stsexpressserver'
|
|
22
|
-
import { Express } from 'express'
|
|
23
|
-
|
|
24
|
-
import { createAdapter as clusterCreateAdapter } from '@socket.io/cluster-adapter'
|
|
25
|
-
import { createAdapter } from "@socket.io/redis-streams-adapter";
|
|
26
|
-
//import { ClusterAdapterWithHeartbeat } from 'socket.io-adaptor';
|
|
27
|
-
|
|
28
|
-
//import { createAdapter } from "@socket.io/redis-adapter";
|
|
29
|
-
|
|
30
|
-
import { createClient, RedisClientType } from 'redis';
|
|
31
|
-
import { Redis } from 'ioredis';
|
|
32
|
-
|
|
33
|
-
import jayson from 'jayson'
|
|
34
|
-
|
|
35
|
-
import { STSTransportLoggerWinston } from './../logger/stsTransportLoggerWinston'
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* todo
|
|
39
|
-
* @typedef {Object} options - todo
|
|
40
|
-
* @property {boolean} [wssServer=false] - Create a web socket server on this worker instance
|
|
41
|
-
*/
|
|
42
|
-
export abstract class ServerProcessBase extends ProcessBase implements IServerProcessBase
|
|
43
|
-
{
|
|
44
|
-
#masterProcessExitTime = goptions.masterProcessExitTime;
|
|
45
|
-
#io: Server | null = null;
|
|
46
|
-
#redisClient: RedisClientType | Redis | null = null;
|
|
47
|
-
#httpServer: any = null;
|
|
48
|
-
#expressServer: STSExpressServer | null = null;
|
|
49
|
-
#sockets: net.Socket[] = [ ];
|
|
50
|
-
#shuttingDown = false;
|
|
51
|
-
|
|
52
|
-
constructor(options: ProcessOptions) {
|
|
53
|
-
super(options);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
get httpServer() {
|
|
57
|
-
return this.#httpServer;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
get io() {
|
|
61
|
-
return this.#io;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
get expressServer(): STSExpressServer | null {
|
|
65
|
-
return this.#expressServer;
|
|
66
|
-
}
|
|
67
|
-
set expressServer(val: STSExpressServer | null) {
|
|
68
|
-
this.#expressServer = val;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Setup server to Prometheus scrapes:
|
|
72
|
-
#SetupPrometheusEndPoints = (expressServer: Express) => {
|
|
73
|
-
// AggregatorRegistry is required here in the worker as well as the master in order for prom-client to work correctly.
|
|
74
|
-
new AggregatorRegistry();
|
|
75
|
-
|
|
76
|
-
const prefix = 'sts_';
|
|
77
|
-
|
|
78
|
-
collectDefaultMetrics({
|
|
79
|
-
labels: { NODE_APP_INSTANCE: process.pid },
|
|
80
|
-
prefix: prefix
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
const c = new Counter({
|
|
84
|
-
name: 'sts_test_counter',
|
|
85
|
-
help: 'Example of a counter',
|
|
86
|
-
labelNames: ['code'],
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
setInterval(() => {
|
|
90
|
-
c.inc({ code: 200 });
|
|
91
|
-
}, 1000).unref();
|
|
92
|
-
|
|
93
|
-
setInterval(() => {
|
|
94
|
-
c.inc({ code: 400 });
|
|
95
|
-
c.inc({ code: 'worker_' + process.pid });
|
|
96
|
-
}, 500).unref();
|
|
97
|
-
|
|
98
|
-
expressServer.get('/metrics', async (req: any, res: any) => {
|
|
99
|
-
try {
|
|
100
|
-
res.set('Content-Type', register.contentType);
|
|
101
|
-
res.end(await register.metrics());
|
|
102
|
-
} catch (ex) {
|
|
103
|
-
res.status(500).end(ex);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
expressServer.get('/metrics/counter', async (req: any, res: any) => {
|
|
108
|
-
try {
|
|
109
|
-
res.set('Content-Type', register.contentType);
|
|
110
|
-
res.end(await register.getSingleMetricAsString('test_counter'));
|
|
111
|
-
} catch (ex) {
|
|
112
|
-
res.status(500).end(ex);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
#SetupTLSServer = async (socket: net.Socket): Promise<void> => {
|
|
118
|
-
// Add a 'close' event handler to this instance of socket
|
|
119
|
-
this.LogInfoMessage('CONNECTED: ' + socket.remoteAddress + ':' + socket.remotePort + ' ' + process.pid);
|
|
120
|
-
this.#sockets.push(socket);
|
|
121
|
-
|
|
122
|
-
//const self = this;
|
|
123
|
-
socket.on('close', (data: any) => {
|
|
124
|
-
const index = this.#sockets.findIndex(function(o) {
|
|
125
|
-
return o.remoteAddress === socket.remoteAddress && o.remotePort === socket.remotePort;
|
|
126
|
-
})
|
|
127
|
-
if (index !== -1) this.#sockets.splice(index, 1);
|
|
128
|
-
this.LogInfoMessage('CLOSED: ' + socket.remoteAddress + ' ' + socket.remotePort + ' ' + process.pid);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
socket.on('data', (data: any) => {
|
|
132
|
-
this.LogInfoMessage('DATA ' + socket.remoteAddress + ': ' + socket.remotePort + ': ' + data);
|
|
133
|
-
socket.write(socket.remoteAddress + ':' + socket.remotePort + " said " + data + '\n');
|
|
134
|
-
|
|
135
|
-
// Write the data back to all the connected, the client will receive it as data from the server
|
|
136
|
-
/*
|
|
137
|
-
self.#sockets.forEach(function(socket, index, array) {
|
|
138
|
-
socket.write(socket.remoteAddress + ':' + socket.remotePort + " said " + data + '\n');
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
*/
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
#SetupRPCServer = async (socket: net.Socket): Promise<void> => {
|
|
146
|
-
this.LogInfoMessage('CONNECTED: ' + socket.remoteAddress + ':' + socket.remotePort + ' ' + process.pid);
|
|
147
|
-
|
|
148
|
-
socket.on('close', (data: any) => {
|
|
149
|
-
this.LogInfoMessage('CLOSED: ' + socket.remoteAddress + ' ' + socket.remotePort + ' ' + process.pid);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
socket.on('data', (data: any) => {
|
|
153
|
-
this.LogInfoMessage('DATA ' + socket.remoteAddress + ': ' + data);
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
#SetupWSSServer = async (): Promise<void> => {
|
|
158
|
-
// socket.io
|
|
159
|
-
// WebSocket
|
|
160
|
-
const options: Partial<ServerOptions> = {
|
|
161
|
-
transports: [ "websocket" ] // or [ "websocket", "polling" ] (to use long-poolling. Note that the order matters)
|
|
162
|
-
// The default path is /socket.io
|
|
163
|
-
// This can be changed with the path option as shown below
|
|
164
|
-
//,path: '/zzz'
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
//this.#io = require("socket.io")(this.#httpServer, options);
|
|
168
|
-
this.#io = new Server(this.#httpServer, options);
|
|
169
|
-
|
|
170
|
-
if (this.options.useSocketIoRedisAdaptor) {
|
|
171
|
-
this.LogInfoMessage(`Using Redis for socket.io cluster management (worker)`);
|
|
172
|
-
if (this.options.socketIoRedisAdaptorUrl) {
|
|
173
|
-
this.LogInfoMessage(`Redis url: [${this.options.socketIoRedisAdaptorUrl}]`);
|
|
174
|
-
this.#redisClient = createClient({url: this.options.socketIoRedisAdaptorUrl});
|
|
175
|
-
} else {
|
|
176
|
-
this.LogInfoMessage(`Redis url: [localhost]`);
|
|
177
|
-
this.#redisClient = createClient();
|
|
178
|
-
}
|
|
179
|
-
await this.#redisClient.connect();
|
|
180
|
-
|
|
181
|
-
//this.#redisClient = new Redis(this.options.socketIoRedisAdaptorUrl as string);
|
|
182
|
-
|
|
183
|
-
this.#io.adapter(createAdapter(this.#redisClient));
|
|
184
|
-
|
|
185
|
-
this.LogInfoMessage(`Redis successfully connected.`);
|
|
186
|
-
} else {
|
|
187
|
-
if (this.options.clusterMode) {
|
|
188
|
-
this.#io.adapter(clusterCreateAdapter() as any);
|
|
189
|
-
this.LogInfoMessage(`Using nodejs cluster mode for socket.io cluster management`);
|
|
190
|
-
} else {
|
|
191
|
-
this.LogInfoMessage(`Not using any adaptors for socket.io cluster management.}`);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// To use a seperate socket server, the code below can be applied.
|
|
196
|
-
// this.#io = require("socket.io")(options);
|
|
197
|
-
// this.#io.adapter(createAdapter());
|
|
198
|
-
// this.#io.listen(3006);
|
|
199
|
-
|
|
200
|
-
this.#io.engine.on("connection_error", (err) => {
|
|
201
|
-
this.LogInfoMessage(err.req); // the request object
|
|
202
|
-
this.LogInfoMessage(err.code); // the error code, for example 1
|
|
203
|
-
this.LogInfoMessage(err.message); // the error message, for example "Session ID unknown"
|
|
204
|
-
this.LogInfoMessage(err.context); // some additional error context
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
#GetTLSOptions = (): JSONObject => {
|
|
209
|
-
return {
|
|
210
|
-
key: fs.readFileSync(this.options.httpsServerKeyPath),
|
|
211
|
-
cert: fs.readFileSync(this.options.httpsServerCertificatePath)
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
#SetupExpressServer = async (useTls: boolean): Promise<void> => {
|
|
216
|
-
if (useTls) {
|
|
217
|
-
this.#httpServer = createServerHttps(this.#GetTLSOptions(), (this.#expressServer as STSExpressServer).App);
|
|
218
|
-
} else {
|
|
219
|
-
this.#httpServer = createServer((this.#expressServer as STSExpressServer).App);
|
|
220
|
-
}
|
|
221
|
-
if (this.options.prometheusSupport === true) {
|
|
222
|
-
this.#SetupPrometheusEndPoints((this.#expressServer as STSExpressServer).App);
|
|
223
|
-
}
|
|
224
|
-
if (this.options.wssServer === true) {
|
|
225
|
-
await this.#SetupWSSServer();
|
|
226
|
-
}
|
|
227
|
-
// https://stackoverflow.com/questions/21342828/node-express-unix-domain-socket-permissions
|
|
228
|
-
//@@httpServer.listen('/tmp/stsrest01.sock').on('listening', () =>
|
|
229
|
-
//@@httpServer.listen('/var/run/sts/stsrest01.sock').on('listening', () =>
|
|
230
|
-
this.#httpServer.listen(this.options.listenPort, () => {
|
|
231
|
-
//@@chmodSync(this.options.port, 511);
|
|
232
|
-
}).on('listening', () => {
|
|
233
|
-
this.LogInfoMessage(`live on ${this.options.endpoint}:${this.options.listenPort}${this.options.apiRoot}`);
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
#SetupTCPRawServer = async (): Promise<void> => {
|
|
238
|
-
// The second parameter is the automatic listener for the secureConnection event from the tls.Server class
|
|
239
|
-
this.#httpServer = tls.createServer(this.#GetTLSOptions(), this.#SetupTLSServer);
|
|
240
|
-
this.#httpServer.listen(this.options.listenPort, 'stscore.stsmda.org', () => {
|
|
241
|
-
this.LogInfoMessage('TCP Server is running on port ' + this.options.listenPort + '.');
|
|
242
|
-
}).on('listening', () => {
|
|
243
|
-
this.LogInfoMessage(`TCP live on ${this.options.endpoint}:${this.options.listenPort}${this.options.apiRoot}`);
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
#SetupJSONRPCServer = async (): Promise<void> => {
|
|
248
|
-
const jaysonServer = new jayson.server();
|
|
249
|
-
// Supported methods here - move somewhere else ...
|
|
250
|
-
jaysonServer.method("add", function(args: any, callback: any) {
|
|
251
|
-
callback(null, args[0] + args[1]);
|
|
252
|
-
});
|
|
253
|
-
this.#httpServer = jaysonServer.tls(this.#GetTLSOptions());
|
|
254
|
-
(this.#httpServer as tls.Server).on('secureConnection', this.#SetupRPCServer);
|
|
255
|
-
this.#httpServer.listen(this.options.listenPort, 'stscore.stsmda.org', () => {
|
|
256
|
-
this.LogInfoMessage('JSON RPC 2.0 Server is running on port ' + this.options.listenPort + '.');
|
|
257
|
-
}).on('listening', () => {
|
|
258
|
-
this.LogInfoMessage(`JSON RPC 2.0 live on ${this.options.endpoint}:${this.options.listenPort}${this.options.apiRoot}`);
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
override get shuttingDown(): boolean {
|
|
263
|
-
return this.#shuttingDown;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
TerminateSocketIO = async (): Promise<void> => {
|
|
267
|
-
if (this.options.wssServer === true && this.#io !== null) {
|
|
268
|
-
const logPrefix = `ServerProcessBase:TerminateSockets():${process.pid}:`;
|
|
269
|
-
this.LogInfoMessage(`${logPrefix} Disconnect SocketIO Sockets.`);
|
|
270
|
-
await Sleep(250);
|
|
271
|
-
await this.#io?.of('/').adapter.close();
|
|
272
|
-
if (this.socketIoServerHelper !== null) {
|
|
273
|
-
await this.socketIoServerHelper.CloseAdaptors();
|
|
274
|
-
await Sleep(50);
|
|
275
|
-
if (this.#redisClient) {
|
|
276
|
-
this.#redisClient.disconnect();
|
|
277
|
-
await Sleep(50);
|
|
278
|
-
}
|
|
279
|
-
this.LogInfoMessage(`${logPrefix} this.socketIoServerHelper.DisconnectSockets()`);
|
|
280
|
-
await this.socketIoServerHelper.DisconnectSockets();
|
|
281
|
-
} else {
|
|
282
|
-
this.LogInfoMessage(`${logPrefix} this.#io.disconnectSockets()`);
|
|
283
|
-
if (this.#redisClient) {
|
|
284
|
-
this.#redisClient.disconnect();
|
|
285
|
-
await Sleep(50);
|
|
286
|
-
}
|
|
287
|
-
this.#io.disconnectSockets();
|
|
288
|
-
}
|
|
289
|
-
this.socketIoServerHelper = null;
|
|
290
|
-
this.#io = null;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
TerminateHTTPServer = async (): Promise<void> => {
|
|
295
|
-
const logPrefix = `ServerProcessBase:TerminateHTTPServer():${process.pid}:`;
|
|
296
|
-
if (this.#httpServer !== null) {
|
|
297
|
-
if (goptions.STSServerType.localeCompare('TCPRAW_TLS') === 0) {
|
|
298
|
-
this.#sockets.forEach((socket: net.Socket, index, array) => {
|
|
299
|
-
this.LogInfoMessage(chalk.yellow(`${logPrefix} TCP Socket destroy, remote address: [${socket.remoteAddress}], remote port: [${socket.remotePort}]`));
|
|
300
|
-
socket.destroy();
|
|
301
|
-
//socket.end();
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
this.LogInfoMessage(`${logPrefix} Closing httpServer.`);
|
|
305
|
-
await this.#httpServer.close();
|
|
306
|
-
this.#httpServer = null;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// Terminate in order;
|
|
311
|
-
// forked worker threads (send signal)
|
|
312
|
-
// De-Register service
|
|
313
|
-
// systeminformation observers
|
|
314
|
-
// instrument timers (gauge etc.)
|
|
315
|
-
// publisher
|
|
316
|
-
// terminate UI (if loaded)
|
|
317
|
-
Terminate = async (clusterPerformExit: boolean, signal?: any): Promise<void> => {
|
|
318
|
-
const logPrefix = `ServerProcessBase:Terminate():${process.pid}:`;
|
|
319
|
-
if (this.#shuttingDown === false) {
|
|
320
|
-
this.#shuttingDown = true;
|
|
321
|
-
|
|
322
|
-
if (signal) {
|
|
323
|
-
this.LogInfoMessage(this.GetSignalColour(signal)(`${logPrefix} Received signal: ${signal}`));
|
|
324
|
-
} else {
|
|
325
|
-
this.LogInfoMessage(this.GetSignalColour(null)(`${logPrefix} Received Terminate without signal.`));
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
await this.ProcessTerminate();
|
|
329
|
-
|
|
330
|
-
this.TerminateUIController();
|
|
331
|
-
|
|
332
|
-
await this.TerminateSocketIO();
|
|
333
|
-
|
|
334
|
-
await this.TerminateHTTPServer();
|
|
335
|
-
|
|
336
|
-
await this.TerminateDatabase();
|
|
337
|
-
|
|
338
|
-
// Output final messages here (before TerminateInstrumentController)
|
|
339
|
-
if (this.options.clusterMode) {
|
|
340
|
-
this.LogInfoMessage(`${logPrefix} clusterPerformExit value: [${clusterPerformExit}]`);
|
|
341
|
-
if (clusterPerformExit) {
|
|
342
|
-
this.LogInfoMessage(`${logPrefix} Process will self terminate with process.exit(0).`);
|
|
343
|
-
} else {
|
|
344
|
-
this.LogInfoMessage(`${logPrefix} Child process will not self terminate. Terminate will be handled by master process.`);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
this.TerminateInstrumentController();
|
|
349
|
-
|
|
350
|
-
//@@ always return here appears to always cleanly exit
|
|
351
|
-
// and cleanly exit from socket.io cluster adaptor
|
|
352
|
-
// without return here, socket.io cluster adaptor terminates in an error state
|
|
353
|
-
// as the implementation relies on cluster.on to send messages to worker threads
|
|
354
|
-
// but these have already been closed from the process.exit(0) below.
|
|
355
|
-
|
|
356
|
-
await Sleep(1000); // Allow socket.io time to clean-up
|
|
357
|
-
|
|
358
|
-
if (this.options.clusterMode === true) {
|
|
359
|
-
if (clusterPerformExit === true) {
|
|
360
|
-
setTimeout(() => {
|
|
361
|
-
process.exit(0);
|
|
362
|
-
}, 0);
|
|
363
|
-
}
|
|
364
|
-
} else {
|
|
365
|
-
this.ProcessExit(this.#masterProcessExitTime);
|
|
366
|
-
}
|
|
367
|
-
} else {
|
|
368
|
-
this.LogInfoMessage(`${logPrefix} Process already terminating.`);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
async SetupServer(): Promise<boolean> {
|
|
373
|
-
return new Promise((resolve, reject) => {
|
|
374
|
-
try {
|
|
375
|
-
this.SetupInstrumentation();
|
|
376
|
-
setTimeout(async () => {
|
|
377
|
-
try {
|
|
378
|
-
await this.SetupServerEx();
|
|
379
|
-
resolve(true);
|
|
380
|
-
} catch (error) {
|
|
381
|
-
reject(error);
|
|
382
|
-
}
|
|
383
|
-
}, 100);
|
|
384
|
-
} catch (error) {
|
|
385
|
-
reject(error);
|
|
386
|
-
}
|
|
387
|
-
})
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
ProcessStarted() {
|
|
391
|
-
const transport = new STSTransportLoggerWinston({
|
|
392
|
-
stsApp: this
|
|
393
|
-
});
|
|
394
|
-
setTimeout(() => {
|
|
395
|
-
(this.options.logger as any).add(transport);
|
|
396
|
-
}, 0);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
async SetupServerEx(): Promise<boolean> {
|
|
400
|
-
this.LogInfoMessage(chalk.green(`ServerProcessBase:SetupServerEx(): Main Process:${process.pid} Starting ...`));
|
|
401
|
-
|
|
402
|
-
this.ProcessStartup();
|
|
403
|
-
|
|
404
|
-
if (this.options.expressServerRouteFactory || this.options.expressServerRouteStaticFactory) {
|
|
405
|
-
this.expressServer = new STSExpressServer(this.options, this);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
this.LogInfoMessage(`ServerProcessBase:SetupServerEx(): Worker instance starting. Service instance Id: [${this.options.serviceInstanceId}]`);
|
|
409
|
-
|
|
410
|
-
// Signal Codes
|
|
411
|
-
// https://en.wikipedia.org/wiki/Signal_(IPC)
|
|
412
|
-
process.on('SIGTERM', async () => {
|
|
413
|
-
this.LogInfoMessage(`ServerProcessBase:SetupServerEx(): SIGTERM signal received for worker: ${process.pid}`);
|
|
414
|
-
await this.Terminate(true, true);
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
process.on('SIGINT', async () => {
|
|
418
|
-
this.LogInfoMessage(`ServerProcessBase:SetupServerEx(): SIGINT signal received for worker: ${process.pid}`);
|
|
419
|
-
await this.Terminate(true, true);
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
process.on('exit', (code) => {
|
|
423
|
-
if (code === 0) {
|
|
424
|
-
this.LogInfoMessage(chalk.green(`ServerProcessBase:SetupServerEx(): Process: ${process.pid} terminated gracefully with code: ${code}`));
|
|
425
|
-
} else {
|
|
426
|
-
this.LogInfoMessage(chalk.red(`ServerProcessBase:SetupServerEx(): Process: ${process.pid} terminated with code: ${code}`));
|
|
427
|
-
}
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
await this.SetupSTSServer();
|
|
431
|
-
|
|
432
|
-
this.ProcessStarted();
|
|
433
|
-
|
|
434
|
-
this.LogInfoMessage(chalk.green(`ServerProcessBase:SetupServerEx(): Main Process:${process.pid} Started`));
|
|
435
|
-
|
|
436
|
-
return true;
|
|
437
|
-
};
|
|
438
|
-
|
|
439
|
-
SetupSTSServer = async(): Promise<void> => {
|
|
440
|
-
switch (goptions.STSServerType) {
|
|
441
|
-
case 'EXPRESS' :
|
|
442
|
-
await this.#SetupExpressServer(false);
|
|
443
|
-
break;
|
|
444
|
-
case 'EXPRESS_TLS' :
|
|
445
|
-
await this.#SetupExpressServer(true);
|
|
446
|
-
break;
|
|
447
|
-
case 'TCPRAW_TLS' :
|
|
448
|
-
await this.#SetupTCPRawServer();
|
|
449
|
-
break;
|
|
450
|
-
case 'JSONRPC2_TLS' :
|
|
451
|
-
await this.#SetupJSONRPCServer();
|
|
452
|
-
break;
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF
|
|
2
|
-
import { goptions } from '@nsshunt/stsconfig'
|
|
3
|
-
|
|
4
|
-
import { Gauge, GaugeTypes, InstrumentGaugeOptions, InstrumentGaugeTelemetry } from '@nsshunt/stsobservability'
|
|
5
|
-
|
|
6
|
-
import { ISingleProcessBase, ProcessOptions } from './../commonTypes';
|
|
7
|
-
import { InstrumentDefinitions } from '@nsshunt/stsobservability'
|
|
8
|
-
import { ServerProcessBase } from './serverprocessbase'
|
|
9
|
-
|
|
10
|
-
import si from 'systeminformation' // https://systeminformation.io/
|
|
11
|
-
|
|
12
|
-
export type EventCb = (socket: any, data: any) => void
|
|
13
|
-
|
|
14
|
-
export class SingleProcessBase extends ServerProcessBase implements ISingleProcessBase
|
|
15
|
-
{
|
|
16
|
-
/**
|
|
17
|
-
*
|
|
18
|
-
* @param {SingleProcessBaseOptions} options
|
|
19
|
-
*/
|
|
20
|
-
constructor(options: ProcessOptions) {
|
|
21
|
-
super(options)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
override CollectAdditionalTelemetry(): void {
|
|
25
|
-
const siValueObject = {
|
|
26
|
-
currentLoad: 'currentLoad'
|
|
27
|
-
}
|
|
28
|
-
si.get(siValueObject).then(data => {
|
|
29
|
-
this.UpdateInstrument(Gauge.CPU_SYSTEM_LOAD_GAUGE, {
|
|
30
|
-
val: data.currentLoad.currentLoad
|
|
31
|
-
} as InstrumentGaugeTelemetry);
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
override GetAdditionalInstruments(): InstrumentDefinitions {
|
|
36
|
-
return [
|
|
37
|
-
[ Gauge.CPU_SYSTEM_LOAD_GAUGE, GaugeTypes.INSTRUMENT_GAUGE, {
|
|
38
|
-
interval: goptions.instrumentationObservationInterval,
|
|
39
|
-
sampleSize: goptions.instrumentationTimeWindow
|
|
40
|
-
} as InstrumentGaugeOptions]
|
|
41
|
-
]
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* UIController (instance of UIController) to manage a console based user interface associated for this node application.
|
|
46
|
-
* @returns UIController instance to manage a console based user interface associated for this node application. Null for no capability.
|
|
47
|
-
*/
|
|
48
|
-
override GetUIController(): any {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
override SetupServerEx = async (): Promise<boolean> => {
|
|
53
|
-
await super.SetupServerEx();
|
|
54
|
-
|
|
55
|
-
this.LogSystemTelemetry();
|
|
56
|
-
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async TerminateApplication() {
|
|
61
|
-
await this.Terminate(false, 'SIGINT');
|
|
62
|
-
}
|
|
63
|
-
}
|