@nsshunt/stsappframework 2.19.173 → 2.19.174
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/.github/workflows/npm-publish.yml +2 -2
- package/dist/authutilsnode.js +152 -178
- package/dist/authutilsnode.js.map +1 -1
- package/dist/masterprocessbase.js +454 -484
- package/dist/masterprocessbase.js.map +1 -1
- package/dist/processbase.js +161 -180
- package/dist/processbase.js.map +1 -1
- package/dist/server.js +3 -16
- package/dist/server.js.map +1 -1
- package/dist/singleprocessbase.js +216 -240
- package/dist/singleprocessbase.js.map +1 -1
- package/dist/socketioHelper.js +132 -145
- package/dist/socketioHelper.js.map +1 -1
- package/dist/stscontrollerbase.js +3 -16
- package/dist/stscontrollerbase.js.map +1 -1
- package/dist/stslatencycontroller.js +9 -20
- package/dist/stslatencycontroller.js.map +1 -1
- package/dist/stsrouterbase.js +6 -19
- package/dist/stsrouterbase.js.map +1 -1
- package/dist/testHelpers.js +238 -262
- package/dist/testHelpers.js.map +1 -1
- package/dist/workerprocessbase.js +297 -321
- package/dist/workerprocessbase.js.map +1 -1
- package/dist/workerprocessbase.test.js +2 -11
- package/dist/workerprocessbase.test.js.map +1 -1
- package/package.json +8 -7
- package/tsconfig.json +28 -9
|
@@ -1,28 +1,7 @@
|
|
|
1
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 __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
12
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
13
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
14
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
15
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
16
|
-
};
|
|
17
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
18
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
19
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
20
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
21
|
-
};
|
|
22
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
4
|
};
|
|
25
|
-
var _SingleProcessBase_masterProcessExitTime, _SingleProcessBase_io, _SingleProcessBase_expressServer, _SingleProcessBase_shuttingDown, _SingleProcessBase_additionalInstruments, _SingleProcessBase_siValueObject, _SingleProcessBase_httpServer, _SingleProcessBase_Terminate;
|
|
26
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
6
|
exports.SingleProcessBase = void 0;
|
|
28
7
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -41,225 +20,28 @@ const processbase_1 = require("./processbase");
|
|
|
41
20
|
const network_js_1 = require("./network.js");
|
|
42
21
|
const server_1 = require("./server");
|
|
43
22
|
class SingleProcessBase extends processbase_1.ProcessBase {
|
|
23
|
+
#masterProcessExitTime = goptions.masterProcessExitTime;
|
|
24
|
+
#io = null;
|
|
25
|
+
#expressServer = null;
|
|
26
|
+
#shuttingDown = false;
|
|
27
|
+
#additionalInstruments = null;
|
|
28
|
+
#siValueObject = {
|
|
29
|
+
currentLoad: 'currentLoad'
|
|
30
|
+
};
|
|
31
|
+
#httpServer = null;
|
|
32
|
+
#Terminate = null;
|
|
44
33
|
/**
|
|
45
34
|
*
|
|
46
35
|
* @param {SingleProcessBaseOptions} options
|
|
47
36
|
*/
|
|
48
37
|
constructor(options) {
|
|
49
38
|
super(options);
|
|
50
|
-
_SingleProcessBase_masterProcessExitTime.set(this, goptions.masterProcessExitTime);
|
|
51
|
-
_SingleProcessBase_io.set(this, null);
|
|
52
|
-
_SingleProcessBase_expressServer.set(this, null);
|
|
53
|
-
_SingleProcessBase_shuttingDown.set(this, false);
|
|
54
|
-
_SingleProcessBase_additionalInstruments.set(this, null);
|
|
55
|
-
_SingleProcessBase_siValueObject.set(this, {
|
|
56
|
-
currentLoad: 'currentLoad'
|
|
57
|
-
});
|
|
58
|
-
_SingleProcessBase_httpServer.set(this, null);
|
|
59
|
-
_SingleProcessBase_Terminate.set(this, null);
|
|
60
|
-
/*
|
|
61
|
-
SetupServer = async () =>
|
|
62
|
-
{
|
|
63
|
-
this.SetupInstrumentation();
|
|
64
|
-
setTimeout(() => {
|
|
65
|
-
this.SetupServerEx();
|
|
66
|
-
}, 100);
|
|
67
|
-
}
|
|
68
|
-
*/
|
|
69
|
-
this.SetupServerEx = () => __awaiter(this, void 0, void 0, function* () {
|
|
70
|
-
this.ProcessStartup();
|
|
71
|
-
if (this.options.expressServerRouteFactory || this.options.expressServerRouteStaticFactory) {
|
|
72
|
-
__classPrivateFieldSet(this, _SingleProcessBase_expressServer, new server_1.STSExpressServer(this.options, this), "f");
|
|
73
|
-
}
|
|
74
|
-
const LogEx = this.LogEx;
|
|
75
|
-
/*
|
|
76
|
-
if (this.instruments !== null) {
|
|
77
|
-
this.instruments[Gauge.LOGGER].consoleLogging = this.options.consoleLogging;
|
|
78
|
-
this.instruments[Gauge.LOGGER].instrumentLogging = this.options.instrumentLogging;
|
|
79
|
-
}
|
|
80
|
-
*/
|
|
81
|
-
LogEx(`Service instance starting. Instance Id: [${this.options.serviceInstanceId}]`);
|
|
82
|
-
LogEx(`Master process:${process.pid} started`);
|
|
83
|
-
const hostaddr = (0, network_js_1.GetFirstNetworkInterface)();
|
|
84
|
-
if (hostaddr !== null) {
|
|
85
|
-
LogEx(`Host Address: ${hostaddr}`);
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
LogEx(`Unknown Host Address.`);
|
|
89
|
-
}
|
|
90
|
-
LogEx(`Server starting with ${numCPUs} Cores/Threads`);
|
|
91
|
-
// https://systeminformation.io/
|
|
92
|
-
const valueObject = {
|
|
93
|
-
system: '*',
|
|
94
|
-
osInfo: '*',
|
|
95
|
-
cpu: '*',
|
|
96
|
-
mem: '*'
|
|
97
|
-
};
|
|
98
|
-
const sysinfo = yield systeminformation_1.default.get(valueObject);
|
|
99
|
-
const hostname = sysinfo.osInfo.hostname;
|
|
100
|
-
LogEx(`Hostname: ${hostname}`);
|
|
101
|
-
LogEx(`System: ${JSON.stringify(sysinfo.system)}`);
|
|
102
|
-
LogEx(`OS Info: ${JSON.stringify(sysinfo.osInfo)}`);
|
|
103
|
-
LogEx(`CPU: ${JSON.stringify(sysinfo.cpu)}`);
|
|
104
|
-
LogEx(`Memory: ${JSON.stringify(sysinfo.mem)}`);
|
|
105
|
-
const GetSignalColour = (signal) => {
|
|
106
|
-
let msgcolor = null;
|
|
107
|
-
if (signal === 'SIGINT') {
|
|
108
|
-
msgcolor = colors_1.default.yellow;
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
msgcolor = colors_1.default.red;
|
|
112
|
-
}
|
|
113
|
-
return msgcolor;
|
|
114
|
-
};
|
|
115
|
-
__classPrivateFieldSet(this, _SingleProcessBase_httpServer, null, "f");
|
|
116
|
-
// Terminate in order;
|
|
117
|
-
// forked worker threads (send signal)
|
|
118
|
-
// De-Register service
|
|
119
|
-
// systeminformation observers
|
|
120
|
-
// instrument timers (gauge etc.)
|
|
121
|
-
// publisher
|
|
122
|
-
// terminate UI (if loaded)
|
|
123
|
-
const Terminate = (signal) => __awaiter(this, void 0, void 0, function* () {
|
|
124
|
-
if (__classPrivateFieldGet(this, _SingleProcessBase_shuttingDown, "f") === false) {
|
|
125
|
-
__classPrivateFieldSet(this, _SingleProcessBase_shuttingDown, true, "f");
|
|
126
|
-
yield this.ProcessTerminate();
|
|
127
|
-
this.ProcessTerminating();
|
|
128
|
-
if (this.GetUIController() !== null) {
|
|
129
|
-
LogEx('Destroy the user interface controller.');
|
|
130
|
-
this.GetUIController().DestroyUI();
|
|
131
|
-
}
|
|
132
|
-
if (signal) {
|
|
133
|
-
LogEx(GetSignalColour(signal)(`Main Process (singleprocess): ${process.pid} received signal: ${signal}`));
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
LogEx(GetSignalColour(null)(`Main Process (singleprocess): ${process.pid} received Terminate without signal.`));
|
|
137
|
-
}
|
|
138
|
-
LogEx(`De-Registering service.`);
|
|
139
|
-
//@@ De-register here ...
|
|
140
|
-
LogEx(`Stopping instruments.`);
|
|
141
|
-
//@@StopInstruments(this.instruments);
|
|
142
|
-
if (this.options.wssServer === true && __classPrivateFieldGet(this, _SingleProcessBase_io, "f") !== null) {
|
|
143
|
-
LogEx(`Disconnect Sockets.`);
|
|
144
|
-
if (this.socketIoHelper !== null) {
|
|
145
|
-
this.socketIoHelper.DisconnectSockets();
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
__classPrivateFieldGet(this, _SingleProcessBase_io, "f").disconnectSockets();
|
|
149
|
-
}
|
|
150
|
-
this.socketIoHelper = null;
|
|
151
|
-
__classPrivateFieldSet(this, _SingleProcessBase_io, null, "f");
|
|
152
|
-
}
|
|
153
|
-
if (this.options.httpServer === true) {
|
|
154
|
-
LogEx(`Closing httpServer.`);
|
|
155
|
-
yield __classPrivateFieldGet(this, _SingleProcessBase_httpServer, "f").close();
|
|
156
|
-
}
|
|
157
|
-
if (this.options.useDatabase) {
|
|
158
|
-
LogEx(`Ending database connections and pools.`);
|
|
159
|
-
yield this.TerminateDatabase();
|
|
160
|
-
//await this.accessLayer.enddatabase();
|
|
161
|
-
}
|
|
162
|
-
// Now allow some time for the workers to die and send any remaining messages ...
|
|
163
|
-
if (this.InstrumentController && this.InstrumentController.Workers.length > 0) {
|
|
164
|
-
LogEx(`Ending publisher.`);
|
|
165
|
-
setTimeout(() => {
|
|
166
|
-
if (this.InstrumentController) {
|
|
167
|
-
this.InstrumentController.InstrumentTerminate();
|
|
168
|
-
}
|
|
169
|
-
}, 100);
|
|
170
|
-
}
|
|
171
|
-
yield (0, stsutils_1.Sleep)(1000); // Allow socket.io time to clean-up
|
|
172
|
-
if (this.options.processExitOnTerminate && this.options.processExitOnTerminate === true) {
|
|
173
|
-
setTimeout(() => {
|
|
174
|
-
LogEx(`Performing process.exit(0).`);
|
|
175
|
-
process.exit(0);
|
|
176
|
-
}, __classPrivateFieldGet(this, _SingleProcessBase_masterProcessExitTime, "f")); // Give the workers time to terminate gracefully
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
LogEx(`Performing process.exit(0) - Immediate.`);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
LogEx(`Service instance stopped.`);
|
|
183
|
-
});
|
|
184
|
-
__classPrivateFieldSet(this, _SingleProcessBase_Terminate, Terminate, "f");
|
|
185
|
-
process.on('SIGINT', () => __awaiter(this, void 0, void 0, function* () {
|
|
186
|
-
yield Terminate('SIGINT');
|
|
187
|
-
}));
|
|
188
|
-
process.on('SIGTERM', () => __awaiter(this, void 0, void 0, function* () {
|
|
189
|
-
yield Terminate('SIGTERM');
|
|
190
|
-
}));
|
|
191
|
-
process.on('exit', (code) => {
|
|
192
|
-
if (code === 0) {
|
|
193
|
-
LogEx(`Main Process: ${process.pid} terminated gracefully with code: ${code}`.green);
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
LogEx(`Main Process: ${process.pid} terminated with code: ${code}`.red);
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
if (this.options.httpServer === true) {
|
|
200
|
-
if (this.options.httpsServer === true) {
|
|
201
|
-
const options = {
|
|
202
|
-
key: fs_1.default.readFileSync(this.options.httpsServerKeyPath),
|
|
203
|
-
cert: fs_1.default.readFileSync(this.options.httpsServerCertificatePath)
|
|
204
|
-
};
|
|
205
|
-
__classPrivateFieldSet(this, _SingleProcessBase_httpServer, (0, https_1.createServer)(options, __classPrivateFieldGet(this, _SingleProcessBase_expressServer, "f").App), "f");
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
__classPrivateFieldSet(this, _SingleProcessBase_httpServer, (0, http_1.createServer)(__classPrivateFieldGet(this, _SingleProcessBase_expressServer, "f").App), "f");
|
|
209
|
-
}
|
|
210
|
-
//this.#httpServer.maxConnections = 50;
|
|
211
|
-
// Setup the web socket server (using socket.io) if enabled.
|
|
212
|
-
if (this.options.wssServer === true) {
|
|
213
|
-
// socket.io
|
|
214
|
-
// WebSocket
|
|
215
|
-
const options = {
|
|
216
|
-
transports: ["websocket"] // or [ "websocket", "polling" ] (to use long-poolling. Note that the order matters)
|
|
217
|
-
// The default path is /socket.io
|
|
218
|
-
// This can be changed with the path option as shown below
|
|
219
|
-
//,path: '/zzz'
|
|
220
|
-
};
|
|
221
|
-
__classPrivateFieldSet(this, _SingleProcessBase_io, new socket_io_1.Server(__classPrivateFieldGet(this, _SingleProcessBase_httpServer, "f"), options), "f");
|
|
222
|
-
// To use a seperate socket server, the code below can be applied.
|
|
223
|
-
// this.#io = require("socket.io")(options);
|
|
224
|
-
// this.#io.listen(3006);
|
|
225
|
-
// LogEx(`socket.io init`);
|
|
226
|
-
__classPrivateFieldGet(this, _SingleProcessBase_io, "f").engine.on("connection_error", (err) => {
|
|
227
|
-
LogEx(err.req); // the request object
|
|
228
|
-
LogEx(err.code); // the error code, for example 1
|
|
229
|
-
LogEx(err.message); // the error message, for example "Session ID unknown"
|
|
230
|
-
LogEx(err.context); // some additional error context
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
try {
|
|
234
|
-
// https://stackoverflow.com/questions/21342828/node-express-unix-domain-socket-permissions
|
|
235
|
-
//@@httpServer.listen('/tmp/stsrest01.sock').on('listening', () =>
|
|
236
|
-
//@@httpServer.listen('/var/run/sts/stsrest01.sock').on('listening', () =>
|
|
237
|
-
__classPrivateFieldGet(this, _SingleProcessBase_httpServer, "f").listen(this.options.listenPort, () => {
|
|
238
|
-
//@@chmodSync(listenPort, 511);
|
|
239
|
-
}).on('listening', () => {
|
|
240
|
-
LogEx(`live on ${this.options.endpoint}:${this.options.listenPort}${this.options.apiRoot}`);
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
catch (error) {
|
|
244
|
-
console.error(error);
|
|
245
|
-
throw error;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
/*
|
|
249
|
-
if (this.publishBroker !== null) {
|
|
250
|
-
setTimeout(() => {
|
|
251
|
-
this.publishBroker.StartPublish();
|
|
252
|
-
}, 0);
|
|
253
|
-
}
|
|
254
|
-
*/
|
|
255
|
-
this.ProcessStarted();
|
|
256
|
-
});
|
|
257
39
|
}
|
|
258
40
|
get httpServer() {
|
|
259
|
-
return
|
|
41
|
+
return this.#httpServer;
|
|
260
42
|
}
|
|
261
43
|
CollectAdditionalTelemetry() {
|
|
262
|
-
systeminformation_1.default.get(
|
|
44
|
+
systeminformation_1.default.get(this.#siValueObject).then(data => {
|
|
263
45
|
this.UpdateInstrument(stsinstrumentation_1.Gauge.CPU_SYSTEM_LOAD_GAUGE, {
|
|
264
46
|
val: data.currentLoad.currentLoad
|
|
265
47
|
});
|
|
@@ -284,40 +66,234 @@ class SingleProcessBase extends processbase_1.ProcessBase {
|
|
|
284
66
|
return null;
|
|
285
67
|
}
|
|
286
68
|
get io() {
|
|
287
|
-
return
|
|
69
|
+
return this.#io;
|
|
288
70
|
}
|
|
289
71
|
ProcessTerminating() {
|
|
290
72
|
return null;
|
|
291
73
|
}
|
|
292
74
|
get expressServer() {
|
|
293
|
-
return
|
|
75
|
+
return this.#expressServer;
|
|
294
76
|
}
|
|
295
77
|
SetupServer() {
|
|
296
78
|
return new Promise((resolve, reject) => {
|
|
297
79
|
try {
|
|
298
80
|
this.SetupInstrumentation();
|
|
299
|
-
setTimeout(() =>
|
|
81
|
+
setTimeout(async () => {
|
|
300
82
|
try {
|
|
301
|
-
|
|
83
|
+
await this.SetupServerEx();
|
|
302
84
|
resolve(true);
|
|
303
85
|
}
|
|
304
86
|
catch (error) {
|
|
305
87
|
reject(error);
|
|
306
88
|
}
|
|
307
|
-
}
|
|
89
|
+
}, 100);
|
|
308
90
|
}
|
|
309
91
|
catch (error) {
|
|
310
92
|
reject(error);
|
|
311
93
|
}
|
|
312
94
|
});
|
|
313
95
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
96
|
+
/*
|
|
97
|
+
SetupServer = async () =>
|
|
98
|
+
{
|
|
99
|
+
this.SetupInstrumentation();
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
this.SetupServerEx();
|
|
102
|
+
}, 100);
|
|
103
|
+
}
|
|
104
|
+
*/
|
|
105
|
+
SetupServerEx = async () => {
|
|
106
|
+
this.ProcessStartup();
|
|
107
|
+
if (this.options.expressServerRouteFactory || this.options.expressServerRouteStaticFactory) {
|
|
108
|
+
this.#expressServer = new server_1.STSExpressServer(this.options, this);
|
|
109
|
+
}
|
|
110
|
+
const LogEx = this.LogEx;
|
|
111
|
+
/*
|
|
112
|
+
if (this.instruments !== null) {
|
|
113
|
+
this.instruments[Gauge.LOGGER].consoleLogging = this.options.consoleLogging;
|
|
114
|
+
this.instruments[Gauge.LOGGER].instrumentLogging = this.options.instrumentLogging;
|
|
115
|
+
}
|
|
116
|
+
*/
|
|
117
|
+
LogEx(`Service instance starting. Instance Id: [${this.options.serviceInstanceId}]`);
|
|
118
|
+
LogEx(`Master process:${process.pid} started`);
|
|
119
|
+
const hostaddr = (0, network_js_1.GetFirstNetworkInterface)();
|
|
120
|
+
if (hostaddr !== null) {
|
|
121
|
+
LogEx(`Host Address: ${hostaddr}`);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
LogEx(`Unknown Host Address.`);
|
|
125
|
+
}
|
|
126
|
+
LogEx(`Server starting with ${numCPUs} Cores/Threads`);
|
|
127
|
+
// https://systeminformation.io/
|
|
128
|
+
const valueObject = {
|
|
129
|
+
system: '*',
|
|
130
|
+
osInfo: '*',
|
|
131
|
+
cpu: '*',
|
|
132
|
+
mem: '*'
|
|
133
|
+
};
|
|
134
|
+
const sysinfo = await systeminformation_1.default.get(valueObject);
|
|
135
|
+
const hostname = sysinfo.osInfo.hostname;
|
|
136
|
+
LogEx(`Hostname: ${hostname}`);
|
|
137
|
+
LogEx(`System: ${JSON.stringify(sysinfo.system)}`);
|
|
138
|
+
LogEx(`OS Info: ${JSON.stringify(sysinfo.osInfo)}`);
|
|
139
|
+
LogEx(`CPU: ${JSON.stringify(sysinfo.cpu)}`);
|
|
140
|
+
LogEx(`Memory: ${JSON.stringify(sysinfo.mem)}`);
|
|
141
|
+
const GetSignalColour = (signal) => {
|
|
142
|
+
let msgcolor = null;
|
|
143
|
+
if (signal === 'SIGINT') {
|
|
144
|
+
msgcolor = colors_1.default.yellow;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
msgcolor = colors_1.default.red;
|
|
148
|
+
}
|
|
149
|
+
return msgcolor;
|
|
150
|
+
};
|
|
151
|
+
this.#httpServer = null;
|
|
152
|
+
// Terminate in order;
|
|
153
|
+
// forked worker threads (send signal)
|
|
154
|
+
// De-Register service
|
|
155
|
+
// systeminformation observers
|
|
156
|
+
// instrument timers (gauge etc.)
|
|
157
|
+
// publisher
|
|
158
|
+
// terminate UI (if loaded)
|
|
159
|
+
const Terminate = async (signal) => {
|
|
160
|
+
if (this.#shuttingDown === false) {
|
|
161
|
+
this.#shuttingDown = true;
|
|
162
|
+
await this.ProcessTerminate();
|
|
163
|
+
this.ProcessTerminating();
|
|
164
|
+
if (this.GetUIController() !== null) {
|
|
165
|
+
LogEx('Destroy the user interface controller.');
|
|
166
|
+
this.GetUIController().DestroyUI();
|
|
167
|
+
}
|
|
168
|
+
if (signal) {
|
|
169
|
+
LogEx(GetSignalColour(signal)(`Main Process (singleprocess): ${process.pid} received signal: ${signal}`));
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
LogEx(GetSignalColour(null)(`Main Process (singleprocess): ${process.pid} received Terminate without signal.`));
|
|
173
|
+
}
|
|
174
|
+
LogEx(`De-Registering service.`);
|
|
175
|
+
//@@ De-register here ...
|
|
176
|
+
LogEx(`Stopping instruments.`);
|
|
177
|
+
//@@StopInstruments(this.instruments);
|
|
178
|
+
if (this.options.wssServer === true && this.#io !== null) {
|
|
179
|
+
LogEx(`Disconnect Sockets.`);
|
|
180
|
+
if (this.socketIoHelper !== null) {
|
|
181
|
+
this.socketIoHelper.DisconnectSockets();
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
this.#io.disconnectSockets();
|
|
185
|
+
}
|
|
186
|
+
this.socketIoHelper = null;
|
|
187
|
+
this.#io = null;
|
|
188
|
+
}
|
|
189
|
+
if (this.options.httpServer === true) {
|
|
190
|
+
LogEx(`Closing httpServer.`);
|
|
191
|
+
await this.#httpServer.close();
|
|
192
|
+
}
|
|
193
|
+
if (this.options.useDatabase) {
|
|
194
|
+
LogEx(`Ending database connections and pools.`);
|
|
195
|
+
await this.TerminateDatabase();
|
|
196
|
+
//await this.accessLayer.enddatabase();
|
|
197
|
+
}
|
|
198
|
+
// Now allow some time for the workers to die and send any remaining messages ...
|
|
199
|
+
if (this.InstrumentController && this.InstrumentController.Workers.length > 0) {
|
|
200
|
+
LogEx(`Ending publisher.`);
|
|
201
|
+
setTimeout(() => {
|
|
202
|
+
if (this.InstrumentController) {
|
|
203
|
+
this.InstrumentController.InstrumentTerminate();
|
|
204
|
+
}
|
|
205
|
+
}, 100);
|
|
206
|
+
}
|
|
207
|
+
await (0, stsutils_1.Sleep)(1000); // Allow socket.io time to clean-up
|
|
208
|
+
if (this.options.processExitOnTerminate && this.options.processExitOnTerminate === true) {
|
|
209
|
+
setTimeout(() => {
|
|
210
|
+
LogEx(`Performing process.exit(0).`);
|
|
211
|
+
process.exit(0);
|
|
212
|
+
}, this.#masterProcessExitTime); // Give the workers time to terminate gracefully
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
LogEx(`Performing process.exit(0) - Immediate.`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
LogEx(`Service instance stopped.`);
|
|
219
|
+
};
|
|
220
|
+
this.#Terminate = Terminate;
|
|
221
|
+
process.on('SIGINT', async () => {
|
|
222
|
+
await Terminate('SIGINT');
|
|
223
|
+
});
|
|
224
|
+
process.on('SIGTERM', async () => {
|
|
225
|
+
await Terminate('SIGTERM');
|
|
318
226
|
});
|
|
227
|
+
process.on('exit', (code) => {
|
|
228
|
+
if (code === 0) {
|
|
229
|
+
LogEx(`Main Process: ${process.pid} terminated gracefully with code: ${code}`.green);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
LogEx(`Main Process: ${process.pid} terminated with code: ${code}`.red);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
if (this.options.httpServer === true) {
|
|
236
|
+
if (this.options.httpsServer === true) {
|
|
237
|
+
const options = {
|
|
238
|
+
key: fs_1.default.readFileSync(this.options.httpsServerKeyPath),
|
|
239
|
+
cert: fs_1.default.readFileSync(this.options.httpsServerCertificatePath)
|
|
240
|
+
};
|
|
241
|
+
this.#httpServer = (0, https_1.createServer)(options, this.#expressServer.App);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
this.#httpServer = (0, http_1.createServer)(this.#expressServer.App);
|
|
245
|
+
}
|
|
246
|
+
//this.#httpServer.maxConnections = 50;
|
|
247
|
+
// Setup the web socket server (using socket.io) if enabled.
|
|
248
|
+
if (this.options.wssServer === true) {
|
|
249
|
+
// socket.io
|
|
250
|
+
// WebSocket
|
|
251
|
+
const options = {
|
|
252
|
+
transports: ["websocket"] // or [ "websocket", "polling" ] (to use long-poolling. Note that the order matters)
|
|
253
|
+
// The default path is /socket.io
|
|
254
|
+
// This can be changed with the path option as shown below
|
|
255
|
+
//,path: '/zzz'
|
|
256
|
+
};
|
|
257
|
+
this.#io = new socket_io_1.Server(this.#httpServer, options);
|
|
258
|
+
// To use a seperate socket server, the code below can be applied.
|
|
259
|
+
// this.#io = require("socket.io")(options);
|
|
260
|
+
// this.#io.listen(3006);
|
|
261
|
+
// LogEx(`socket.io init`);
|
|
262
|
+
this.#io.engine.on("connection_error", (err) => {
|
|
263
|
+
LogEx(err.req); // the request object
|
|
264
|
+
LogEx(err.code); // the error code, for example 1
|
|
265
|
+
LogEx(err.message); // the error message, for example "Session ID unknown"
|
|
266
|
+
LogEx(err.context); // some additional error context
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
try {
|
|
270
|
+
// https://stackoverflow.com/questions/21342828/node-express-unix-domain-socket-permissions
|
|
271
|
+
//@@httpServer.listen('/tmp/stsrest01.sock').on('listening', () =>
|
|
272
|
+
//@@httpServer.listen('/var/run/sts/stsrest01.sock').on('listening', () =>
|
|
273
|
+
this.#httpServer.listen(this.options.listenPort, () => {
|
|
274
|
+
//@@chmodSync(listenPort, 511);
|
|
275
|
+
}).on('listening', () => {
|
|
276
|
+
LogEx(`live on ${this.options.endpoint}:${this.options.listenPort}${this.options.apiRoot}`);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
console.error(error);
|
|
281
|
+
throw error;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/*
|
|
285
|
+
if (this.publishBroker !== null) {
|
|
286
|
+
setTimeout(() => {
|
|
287
|
+
this.publishBroker.StartPublish();
|
|
288
|
+
}, 0);
|
|
289
|
+
}
|
|
290
|
+
*/
|
|
291
|
+
this.ProcessStarted();
|
|
292
|
+
};
|
|
293
|
+
async Terminate() {
|
|
294
|
+
await this.#Terminate('SIGINT');
|
|
295
|
+
this.#Terminate = null;
|
|
319
296
|
}
|
|
320
297
|
}
|
|
321
298
|
exports.SingleProcessBase = SingleProcessBase;
|
|
322
|
-
_SingleProcessBase_masterProcessExitTime = new WeakMap(), _SingleProcessBase_io = new WeakMap(), _SingleProcessBase_expressServer = new WeakMap(), _SingleProcessBase_shuttingDown = new WeakMap(), _SingleProcessBase_additionalInstruments = new WeakMap(), _SingleProcessBase_siValueObject = new WeakMap(), _SingleProcessBase_httpServer = new WeakMap(), _SingleProcessBase_Terminate = new WeakMap();
|
|
323
299
|
//# sourceMappingURL=singleprocessbase.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"singleprocessbase.js","sourceRoot":"","sources":["../src/singleprocessbase.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"singleprocessbase.js","sourceRoot":"","sources":["../src/singleprocessbase.ts"],"names":[],"mappings":"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"}
|