@nsshunt/stsappframework 3.1.235 → 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
|
@@ -0,0 +1,1954 @@
|
|
|
1
|
+
(function(global, factory) {
|
|
2
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@nsshunt/stsutils"), require("node:fs"), require("/home/runner/work/stsappframework/stsappframework/node_modules/systeminformation/lib/index.js"), require("axios"), require("node:cluster"), require("/home/runner/work/stsappframework/stsappframework/node_modules/chalk/source/index.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/express/index.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/@socket.io/cluster-adapter/dist/index.js"), require("node:https"), require("node:http"), require("/home/runner/work/stsappframework/stsappframework/node_modules/prom-client/index.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/@nsshunt/stsconfig/dist/stsconfig.mjs"), require("/home/runner/work/stsappframework/stsappframework/node_modules/@nsshunt/stsobservability/dist/stsobservability.mjs"), require("/home/runner/work/stsappframework/stsappframework/node_modules/pidusage/index.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/process/browser.js"), require("os"), require("/home/runner/work/stsappframework/stsappframework/node_modules/@nsshunt/stsdatamanagement/dist/dbaccess.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/http-status-codes/build/es/index.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/tiny-emitter/index.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/winston-transport/dist/index.js"), require("node:tls"), require("/home/runner/work/stsappframework/stsappframework/node_modules/socket.io/wrapper.mjs"), require("/home/runner/work/stsappframework/stsappframework/node_modules/cors/lib/index.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/cookie-parser/index.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/uuid/dist/esm-browser/index.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/on-headers/index.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/@socket.io/redis-streams-adapter/dist/index.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/redis/dist/index.js"), require("/home/runner/work/stsappframework/stsappframework/node_modules/jayson/index.js")) : typeof define === "function" && define.amd ? define(["exports", "@nsshunt/stsutils", "node:fs", "/home/runner/work/stsappframework/stsappframework/node_modules/systeminformation/lib/index.js", "axios", "node:cluster", "/home/runner/work/stsappframework/stsappframework/node_modules/chalk/source/index.js", "/home/runner/work/stsappframework/stsappframework/node_modules/express/index.js", "/home/runner/work/stsappframework/stsappframework/node_modules/@socket.io/cluster-adapter/dist/index.js", "node:https", "node:http", "/home/runner/work/stsappframework/stsappframework/node_modules/prom-client/index.js", "/home/runner/work/stsappframework/stsappframework/node_modules/@nsshunt/stsconfig/dist/stsconfig.mjs", "/home/runner/work/stsappframework/stsappframework/node_modules/@nsshunt/stsobservability/dist/stsobservability.mjs", "/home/runner/work/stsappframework/stsappframework/node_modules/pidusage/index.js", "/home/runner/work/stsappframework/stsappframework/node_modules/process/browser.js", "os", "/home/runner/work/stsappframework/stsappframework/node_modules/@nsshunt/stsdatamanagement/dist/dbaccess.js", "/home/runner/work/stsappframework/stsappframework/node_modules/http-status-codes/build/es/index.js", "/home/runner/work/stsappframework/stsappframework/node_modules/tiny-emitter/index.js", "/home/runner/work/stsappframework/stsappframework/node_modules/winston-transport/dist/index.js", "node:tls", "/home/runner/work/stsappframework/stsappframework/node_modules/socket.io/wrapper.mjs", "/home/runner/work/stsappframework/stsappframework/node_modules/cors/lib/index.js", "/home/runner/work/stsappframework/stsappframework/node_modules/cookie-parser/index.js", "/home/runner/work/stsappframework/stsappframework/node_modules/uuid/dist/esm-browser/index.js", "/home/runner/work/stsappframework/stsappframework/node_modules/on-headers/index.js", "/home/runner/work/stsappframework/stsappframework/node_modules/@socket.io/redis-streams-adapter/dist/index.js", "/home/runner/work/stsappframework/stsappframework/node_modules/redis/dist/index.js", "/home/runner/work/stsappframework/stsappframework/node_modules/jayson/index.js"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["@nsshunt/stsappframework"] = {}, global.stsutils, global.https, global.si, global.axios, global.cluster, global.chalk, global.express, global.index_js$3, global.https, global.http, global.index_js$2, global.stsconfig_mjs, global.stsobservability_mjs, global.pidusage, global.browser_js, global.os, global.dbaccess_js, global.index_js$1, global.index_js, global.Transport, global.tls, global.wrapper_mjs, global.cors, global.cookieParser, global.index_js$4, global.onHeaders, global.index_js$6, global.index_js$5, global.jayson));
|
|
3
|
+
})(this, function(exports2, stsutils, fs, si, axios, cluster, chalk, express, index_js$3, node_https, node_http, index_js$2, stsconfig_mjs, stsobservability_mjs, pidusage, browser_js, os, dbaccess_js, index_js$1, index_js, Transport, tls, wrapper_mjs, cors, cookieParser, index_js$4, onHeaders, index_js$6, index_js$5, jayson) {
|
|
4
|
+
"use strict";var __defProp = Object.defineProperty;
|
|
5
|
+
var __typeError = (msg) => {
|
|
6
|
+
throw TypeError(msg);
|
|
7
|
+
};
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
10
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
11
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
12
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
13
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
14
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
15
|
+
var __privateWrapper = (obj, member, setter, getter) => ({
|
|
16
|
+
set _(value) {
|
|
17
|
+
__privateSet(obj, member, value, setter);
|
|
18
|
+
},
|
|
19
|
+
get _() {
|
|
20
|
+
return __privateGet(obj, member, getter);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
var _options, _instrumentController, _systemInformationInterval, _socketIoServerHelper, _accessLayer, _ProcessBase_instances, GetFormattedLogMessage_fn, _UpdatePGPoolManagerInstrument, _options2, _masterProcessExitTime, _childProcessExitTime, _siValueObject, _httpServer, _metricsServer, _aggregatorRegistry, _checkLatency, _killWorkers, _workers, _shuttingDown, _agentManager, _MasterProcessBase_instances, LogErrorMessage_fn, LogDebugMessage_fn, WorkerMessageEvent_fn, _InitCluster, _SetupPrometheusForMaster, _CheckLatency, _GetLatency, _LatencyRequestCompleted, __KillWorker, _UpdateWorkersInstrument, _processIPCCommand, _SpawnWorker, _tinyEmitter, _socketCollection, _id, _ServerNetworkMiddleware_instances, LogSillyMessage_fn, LogErrorMessage_fn2, _GetRequestContentSize, _app, _masterProcessExitTime2, _io, _redisClient, _httpServer2, _expressServer, _sockets, _shuttingDown2, _SetupPrometheusEndPoints, _SetupTLSServer, _SetupRPCServer, _SetupWSSServer, _GetTLSOptions, _SetupExpressServer, _SetupTCPRawServer, _SetupJSONRPCServer, _inFlightMessage, _requestResponseMessageTimeout, _pingTimeout, _SendMessageToParentProcess, _stsApp, _router, _stsApp2, _options3;
|
|
25
|
+
function CreateServiceProcessContext(serviceName, serviceVersion, serviceInstanceId, hostName, processId, parentProcessId) {
|
|
26
|
+
const checkParams = [
|
|
27
|
+
["servicename", serviceName],
|
|
28
|
+
["serviceversion", serviceVersion],
|
|
29
|
+
["hostname", hostName],
|
|
30
|
+
["serviceInstanceId", serviceInstanceId]
|
|
31
|
+
];
|
|
32
|
+
stsutils.CheckValidChar(checkParams);
|
|
33
|
+
return {
|
|
34
|
+
nid: `${serviceName}${stsutils.ModelDelimeter.COMPONENT_SEPERATOR}${serviceVersion}${stsutils.ModelDelimeter.SEPERATOR}${serviceInstanceId}${stsutils.ModelDelimeter.COMPONENT_SEPERATOR}${hostName}${stsutils.ModelDelimeter.NID_SEPERATOR}${processId.toString()}${stsutils.ModelDelimeter.COMPONENT_SEPERATOR}${parentProcessId.toString()}`,
|
|
35
|
+
serviceName,
|
|
36
|
+
serviceVersion,
|
|
37
|
+
serviceInstanceId,
|
|
38
|
+
hostName,
|
|
39
|
+
processId: processId.toString(),
|
|
40
|
+
parentProcessId: parentProcessId.toString()
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
var IPCMessageCommand = /* @__PURE__ */ ((IPCMessageCommand2) => {
|
|
44
|
+
IPCMessageCommand2["AddWorker"] = "AddWorker";
|
|
45
|
+
IPCMessageCommand2["DeleteWorker"] = "DeleteWorker";
|
|
46
|
+
IPCMessageCommand2["GetConfig"] = "GetConfig";
|
|
47
|
+
return IPCMessageCommand2;
|
|
48
|
+
})(IPCMessageCommand || {});
|
|
49
|
+
const iss = `https://stscore.stsmda.org/oauth2/v2.0`;
|
|
50
|
+
function GetNetworkInterfaces() {
|
|
51
|
+
const nets = os.networkInterfaces();
|
|
52
|
+
const results = {};
|
|
53
|
+
for (const name of Object.keys(nets)) {
|
|
54
|
+
for (const net of nets[name]) {
|
|
55
|
+
if (net.family === "IPv4" && !net.internal) {
|
|
56
|
+
if (!results[name]) {
|
|
57
|
+
results[name] = [];
|
|
58
|
+
}
|
|
59
|
+
results[name].push(net.address);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return results;
|
|
64
|
+
}
|
|
65
|
+
function GetFirstNetworkInterface() {
|
|
66
|
+
const nics = GetNetworkInterfaces();
|
|
67
|
+
let hostaddr = null;
|
|
68
|
+
for (const nic in nics) {
|
|
69
|
+
const val = nics[nic];
|
|
70
|
+
if (val.length > 0) {
|
|
71
|
+
hostaddr = val[0];
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return hostaddr;
|
|
76
|
+
}
|
|
77
|
+
class ProcessBase extends index_js.TinyEmitter {
|
|
78
|
+
//#redisMessageHandler: RedisMessageHandler | null = null;
|
|
79
|
+
constructor(options) {
|
|
80
|
+
super();
|
|
81
|
+
__privateAdd(this, _ProcessBase_instances);
|
|
82
|
+
__privateAdd(this, _options);
|
|
83
|
+
__privateAdd(this, _instrumentController, null);
|
|
84
|
+
__privateAdd(this, _systemInformationInterval, null);
|
|
85
|
+
__privateAdd(this, _socketIoServerHelper, null);
|
|
86
|
+
__privateAdd(this, _accessLayer, null);
|
|
87
|
+
__publicField(this, "ProcessStartup", () => {
|
|
88
|
+
const ExecuteGetStats = async () => {
|
|
89
|
+
const startTime = performance.now();
|
|
90
|
+
if (__privateGet(this, _instrumentController)) {
|
|
91
|
+
const stats = await pidusage(process.pid);
|
|
92
|
+
let useStatsCpu = stats.cpu;
|
|
93
|
+
if (useStatsCpu < 0.01) {
|
|
94
|
+
useStatsCpu = 0.01;
|
|
95
|
+
}
|
|
96
|
+
__privateGet(this, _instrumentController).UpdateInstrument(stsobservability_mjs.Gauge.CPU_LOAD_GAUGE, {
|
|
97
|
+
val: useStatsCpu
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const usage = browser_js.memoryUsage();
|
|
101
|
+
const telemetry = {
|
|
102
|
+
r: usage.rss,
|
|
103
|
+
t: usage.heapTotal,
|
|
104
|
+
u: usage.heapUsed,
|
|
105
|
+
x: usage.external,
|
|
106
|
+
a: usage.arrayBuffers
|
|
107
|
+
};
|
|
108
|
+
this.UpdateInstrument(stsobservability_mjs.Gauge.OBJECT_GAUGE, {
|
|
109
|
+
val: telemetry
|
|
110
|
+
});
|
|
111
|
+
this.CollectAdditionalTelemetry();
|
|
112
|
+
const totalTime = performance.now() - startTime;
|
|
113
|
+
const nextLoopTime = stsconfig_mjs.goptions.systemInformationInterval - totalTime;
|
|
114
|
+
__privateSet(this, _systemInformationInterval, setTimeout(ExecuteGetStats, nextLoopTime).unref());
|
|
115
|
+
};
|
|
116
|
+
__privateSet(this, _systemInformationInterval, setTimeout(ExecuteGetStats, stsconfig_mjs.goptions.systemInformationInterval).unref());
|
|
117
|
+
if (this.options.useDatabase) {
|
|
118
|
+
this.accessLayer;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
__publicField(this, "UpdateInstrument", (instrumentName, telemetry) => {
|
|
122
|
+
if (__privateGet(this, _instrumentController)) {
|
|
123
|
+
__privateGet(this, _instrumentController).UpdateInstrument(instrumentName, telemetry);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
__publicField(this, "ProcessExit", (processExitDelay) => {
|
|
127
|
+
if (this.options.processExitOnTerminate && this.options.processExitOnTerminate === true) {
|
|
128
|
+
setTimeout(() => {
|
|
129
|
+
this.LogInfoMessage(`Performing process.exit(0).`);
|
|
130
|
+
process.exit(0);
|
|
131
|
+
}, processExitDelay);
|
|
132
|
+
} else {
|
|
133
|
+
this.LogInfoMessage(`Performing process.exit(0) - Immediate.`);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
__publicField(this, "TerminateInstrumentController", () => {
|
|
137
|
+
if (this.InstrumentController) {
|
|
138
|
+
this.LogInfoMessage(`ProcessBase:TerminateInstrumentController()`);
|
|
139
|
+
setTimeout(() => {
|
|
140
|
+
if (this.InstrumentController) {
|
|
141
|
+
this.InstrumentController.EndPublish();
|
|
142
|
+
}
|
|
143
|
+
}, 100);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
__publicField(this, "TerminateUIController", () => {
|
|
147
|
+
if (this.GetUIController() !== null) {
|
|
148
|
+
this.LogInfoMessage("ProcessBase:TerminateUIController(): Destroy the user interface controller.");
|
|
149
|
+
this.GetUIController().DestroyUI();
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
__privateAdd(this, _UpdatePGPoolManagerInstrument, (data) => {
|
|
153
|
+
this.UpdateInstrument(stsobservability_mjs.Gauge.CONNECTION_POOL_TOTAL_GAUGE, {
|
|
154
|
+
val: data.totalCount
|
|
155
|
+
});
|
|
156
|
+
this.UpdateInstrument(stsobservability_mjs.Gauge.CONNECTION_POOL_IDLE_GAUGE, {
|
|
157
|
+
val: data.idleCount
|
|
158
|
+
});
|
|
159
|
+
this.UpdateInstrument(stsobservability_mjs.Gauge.CONNECTION_POOL_WAITING_GAUGE, {
|
|
160
|
+
val: data.waitingCount
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
__publicField(this, "GetNumCPUs", async () => {
|
|
164
|
+
const valueObject = {
|
|
165
|
+
cpu: "*"
|
|
166
|
+
};
|
|
167
|
+
const sysinfo = await si.get(valueObject);
|
|
168
|
+
let numCPUs = 2;
|
|
169
|
+
if (stsconfig_mjs.goptions.useCPUs > 0) {
|
|
170
|
+
if (stsconfig_mjs.goptions.useCPUs >= 1) {
|
|
171
|
+
numCPUs = stsconfig_mjs.goptions.useCPUs;
|
|
172
|
+
} else {
|
|
173
|
+
numCPUs = Math.round(sysinfo.cpu.cores * stsconfig_mjs.goptions.useCPUs);
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
numCPUs = sysinfo.cpu.physicalCores;
|
|
177
|
+
}
|
|
178
|
+
return numCPUs;
|
|
179
|
+
});
|
|
180
|
+
__publicField(this, "LogSystemTelemetry", async () => {
|
|
181
|
+
const valueObject = {
|
|
182
|
+
system: "*",
|
|
183
|
+
osInfo: "*",
|
|
184
|
+
cpu: "*",
|
|
185
|
+
mem: "*"
|
|
186
|
+
};
|
|
187
|
+
const sysinfo = await si.get(valueObject);
|
|
188
|
+
const numCPUs = await this.GetNumCPUs();
|
|
189
|
+
const hostname = sysinfo.osInfo.hostname;
|
|
190
|
+
const hostaddr = GetFirstNetworkInterface();
|
|
191
|
+
if (hostaddr !== null) {
|
|
192
|
+
this.LogInfoMessage(`Host Address: ${hostaddr}`);
|
|
193
|
+
} else {
|
|
194
|
+
this.LogInfoMessage(`Unknown Host Address.`);
|
|
195
|
+
}
|
|
196
|
+
this.LogInfoMessage(`Server starting with ${numCPUs} Cores/Threads`);
|
|
197
|
+
this.LogInfoMessage(`Hostname: ${hostname}`);
|
|
198
|
+
this.LogInfoMessage(`System: ${JSON.stringify(sysinfo.system)}`);
|
|
199
|
+
this.LogInfoMessage(`OS Info: ${JSON.stringify(sysinfo.osInfo)}`);
|
|
200
|
+
this.LogInfoMessage(`CPU: ${JSON.stringify(sysinfo.cpu)}`);
|
|
201
|
+
this.LogInfoMessage(`Memory: ${JSON.stringify(sysinfo.mem)}`);
|
|
202
|
+
});
|
|
203
|
+
__publicField(this, "GetSignalColour", (signal) => {
|
|
204
|
+
let msgcolor = null;
|
|
205
|
+
if (signal === "SIGINT") {
|
|
206
|
+
msgcolor = chalk.yellow;
|
|
207
|
+
} else {
|
|
208
|
+
msgcolor = chalk.red;
|
|
209
|
+
}
|
|
210
|
+
return msgcolor;
|
|
211
|
+
});
|
|
212
|
+
__privateSet(this, _options, options);
|
|
213
|
+
if (options.serviceName) {
|
|
214
|
+
this.options.serviceProcessContext = CreateServiceProcessContext(
|
|
215
|
+
options.serviceName,
|
|
216
|
+
options.serviceVersion,
|
|
217
|
+
options.serviceInstanceId,
|
|
218
|
+
os.hostname(),
|
|
219
|
+
process.pid,
|
|
220
|
+
options.isMaster ? process.pid : process.ppid
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
LogErrorMessage(message) {
|
|
225
|
+
this.options.logger.error(__privateMethod(this, _ProcessBase_instances, GetFormattedLogMessage_fn).call(this, message));
|
|
226
|
+
}
|
|
227
|
+
LogInfoMessage(message) {
|
|
228
|
+
this.options.logger.info(__privateMethod(this, _ProcessBase_instances, GetFormattedLogMessage_fn).call(this, message));
|
|
229
|
+
}
|
|
230
|
+
LogMessageToLoggerInstrument(message) {
|
|
231
|
+
this.UpdateInstrument(stsobservability_mjs.Gauge.LOGGER, {
|
|
232
|
+
LogMessage: __privateMethod(this, _ProcessBase_instances, GetFormattedLogMessage_fn).call(this, message)
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
get options() {
|
|
236
|
+
return __privateGet(this, _options);
|
|
237
|
+
}
|
|
238
|
+
get shuttingDown() {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
SetupInstrumentation() {
|
|
242
|
+
if (!this.options.serviceProcessContext) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
let publishTransportOptions = null;
|
|
246
|
+
if (stsconfig_mjs.goptions.observabilityPublishMode.localeCompare("PROXY") === 0) {
|
|
247
|
+
publishTransportOptions = {
|
|
248
|
+
transportType: stsobservability_mjs.TransportType.RESTAPI,
|
|
249
|
+
url: `${stsconfig_mjs.goptions.imendpoint}:${stsconfig_mjs.goptions.import}${stsconfig_mjs.goptions.imapiroot}/publishmessage`,
|
|
250
|
+
// socketPath: '/var/run/sts/stsrest01.sock'
|
|
251
|
+
agentOptions: {
|
|
252
|
+
keepAlive: stsconfig_mjs.goptions.keepAlive,
|
|
253
|
+
maxSockets: stsconfig_mjs.goptions.maxSockets,
|
|
254
|
+
maxTotalSockets: stsconfig_mjs.goptions.maxTotalSockets,
|
|
255
|
+
maxFreeSockets: stsconfig_mjs.goptions.maxFreeSockets,
|
|
256
|
+
timeout: stsconfig_mjs.goptions.timeout,
|
|
257
|
+
rejectUnauthorized: stsconfig_mjs.goptions.isProduction
|
|
258
|
+
// Allows self signed certs in non production mode(s)
|
|
259
|
+
},
|
|
260
|
+
logger: this.options.publisherLogger
|
|
261
|
+
};
|
|
262
|
+
} else {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const httpServer = stsconfig_mjs.goptions.STSServerType.localeCompare("EXPRESS") === 0 || stsconfig_mjs.goptions.STSServerType.localeCompare("EXPRESS_TLS") === 0;
|
|
266
|
+
const instrumentControllerOptions = {
|
|
267
|
+
processContext: this.options.serviceProcessContext,
|
|
268
|
+
//payloadType: InstrumentPayloadType.service,
|
|
269
|
+
consoleLogging: this.options.consoleLogging,
|
|
270
|
+
instrumentLogging: this.options.instrumentLogging,
|
|
271
|
+
httpServer,
|
|
272
|
+
instrumentationObservationInterval: this.options.instrumentationObservationInterval,
|
|
273
|
+
instrumentationTimeWindow: this.options.instrumentationTimeWindow,
|
|
274
|
+
logger: this.options.publisherLogger,
|
|
275
|
+
publishInterval: this.options.publishInterval,
|
|
276
|
+
publishPostFailInterval: 5e3,
|
|
277
|
+
//@@
|
|
278
|
+
instrumentDefinitions: stsobservability_mjs.GetInstruments("service"),
|
|
279
|
+
publishTransportBaseOptions: publishTransportOptions,
|
|
280
|
+
autoStart: true
|
|
281
|
+
/*
|
|
282
|
+
[
|
|
283
|
+
...this.#GetDefaultServiceInstruments(httpServer),
|
|
284
|
+
...this.GetAdditionalInstruments()
|
|
285
|
+
]
|
|
286
|
+
*/
|
|
287
|
+
};
|
|
288
|
+
__privateSet(this, _instrumentController, new stsobservability_mjs.PublishInstrumentController(instrumentControllerOptions));
|
|
289
|
+
}
|
|
290
|
+
/*
|
|
291
|
+
#GetDefaultServiceInstruments(httpServer: boolean): InstrumentDefinitions {
|
|
292
|
+
const standardInstruments: InstrumentDefinitions = [
|
|
293
|
+
[ Gauge.TIMER_GAUGE, GaugeTypes.INSTRUMENT_TIMER ],
|
|
294
|
+
[ Gauge.LOGGER, GaugeTypes.INSTRUMENT_LOG, {
|
|
295
|
+
consoleLogging: this.options.consoleLogging,
|
|
296
|
+
instrumentLogging: this.options.instrumentLogging } as InstrumentLogOptions],
|
|
297
|
+
[ Gauge.NETWORK_RX_GAUGE , GaugeTypes.INSTRUMENT_VELOCITY ],
|
|
298
|
+
[ Gauge.NETWORK_TX_GAUGE, GaugeTypes.INSTRUMENT_VELOCITY ],
|
|
299
|
+
[ Gauge.CPU_LOAD_GAUGE, GaugeTypes.INSTRUMENT_GAUGE, {
|
|
300
|
+
interval: this.options.instrumentationObservationInterval,
|
|
301
|
+
sampleSize: this.options.instrumentationTimeWindow } as InstrumentGaugeOptions],
|
|
302
|
+
[ Gauge.OBJECT_GAUGE, GaugeTypes.INSTRUMENT_OBJECT, {
|
|
303
|
+
label:'InstrumentObjectMaster' } as InstrumentObjectOptions]
|
|
304
|
+
];
|
|
305
|
+
|
|
306
|
+
let httpServerInstruments: InstrumentDefinitions = [ ];
|
|
307
|
+
if (httpServer) {
|
|
308
|
+
httpServerInstruments = [
|
|
309
|
+
[ Gauge.REQUEST_COUNT_GAUGE, GaugeTypes.INSTRUMENT_GAUGE ], // Total number of requests serviced
|
|
310
|
+
[ Gauge.AUTHENTICATION_COUNT_GAUGE, GaugeTypes.INSTRUMENT_GAUGE ], // Total number of new token requests
|
|
311
|
+
[ Gauge.AUTHENTICATION_ERROR_COUNT_GAUGE, GaugeTypes.INSTRUMENT_GAUGE ], // Total number of new token requests errors
|
|
312
|
+
[ Gauge.AUTHENTICATION_RETRY_COUNT_GAUGE, GaugeTypes.INSTRUMENT_GAUGE ], // Total number of new token requests retries
|
|
313
|
+
|
|
314
|
+
[ Gauge.ACTIVE_REQUEST_GAUGE, GaugeTypes.INSTRUMENT_GAUGE, {
|
|
315
|
+
interval: this.options.instrumentationObservationInterval,
|
|
316
|
+
sampleSize: this.options.instrumentationTimeWindow } as InstrumentGaugeOptions],
|
|
317
|
+
[ Gauge.DURATION_GAUGE, GaugeTypes.INSTRUMENT_GAUGE, {
|
|
318
|
+
interval: this.options.instrumentationObservationInterval,
|
|
319
|
+
sampleSize: this.options.instrumentationTimeWindow } as InstrumentGaugeOptions],
|
|
320
|
+
[ Gauge.DURATION_HISTOGRAM_GAUGE, GaugeTypes.INSTRUMENT_HISTOGRAM ],
|
|
321
|
+
[ Gauge.CONNECTION_COUNT_GAUGE, GaugeTypes.INSTRUMENT_GAUGE, {
|
|
322
|
+
interval: this.options.instrumentationObservationInterval,
|
|
323
|
+
sampleSize: this.options.instrumentationTimeWindow } as InstrumentGaugeOptions],
|
|
324
|
+
|
|
325
|
+
[ Gauge.CONNECTION_POOL_TOTAL_GAUGE, GaugeTypes.INSTRUMENT_GAUGE ],
|
|
326
|
+
[ Gauge.CONNECTION_POOL_IDLE_GAUGE, GaugeTypes.INSTRUMENT_GAUGE ],
|
|
327
|
+
[ Gauge.CONNECTION_POOL_WAITING_GAUGE, GaugeTypes.INSTRUMENT_GAUGE ],
|
|
328
|
+
[ Gauge.VELOCITY_GAUGE, GaugeTypes.INSTRUMENT_VELOCITY ], // Requests per second
|
|
329
|
+
[ Gauge.ERROR_COUNT_GAUGE, GaugeTypes.INSTRUMENT_GAUGE ],
|
|
330
|
+
[ Gauge.RETRY_COUNT_GAUGE, GaugeTypes.INSTRUMENT_GAUGE ],
|
|
331
|
+
[ Gauge.LATENCY_GAUGE, GaugeTypes.INSTRUMENT_GAUGE, {
|
|
332
|
+
interval: this.options.instrumentationObservationInterval,
|
|
333
|
+
sampleSize: this.options.instrumentationTimeWindow } as InstrumentGaugeOptions],
|
|
334
|
+
[ Gauge.LATENCY_HISTOGRAM_GAUGE, GaugeTypes.INSTRUMENT_HISTOGRAM ],
|
|
335
|
+
[ Gauge.CORE_COUNT_GAUGE, GaugeTypes.INSTRUMENT_GAUGE ]
|
|
336
|
+
]
|
|
337
|
+
}
|
|
338
|
+
return [
|
|
339
|
+
...standardInstruments,
|
|
340
|
+
...httpServerInstruments
|
|
341
|
+
]
|
|
342
|
+
}
|
|
343
|
+
*/
|
|
344
|
+
GetAdditionalInstruments() {
|
|
345
|
+
return [];
|
|
346
|
+
}
|
|
347
|
+
CollectAdditionalTelemetry() {
|
|
348
|
+
}
|
|
349
|
+
get InstrumentController() {
|
|
350
|
+
return __privateGet(this, _instrumentController);
|
|
351
|
+
}
|
|
352
|
+
InstrumentExists(instrumentName) {
|
|
353
|
+
if (__privateGet(this, _instrumentController)) {
|
|
354
|
+
return __privateGet(this, _instrumentController).InstrumentExists(instrumentName);
|
|
355
|
+
}
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
async ProcessTerminate() {
|
|
359
|
+
this.emit("ProcessTerminate");
|
|
360
|
+
if (__privateGet(this, _systemInformationInterval)) {
|
|
361
|
+
clearTimeout(__privateGet(this, _systemInformationInterval));
|
|
362
|
+
}
|
|
363
|
+
__privateSet(this, _systemInformationInterval, null);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* UIController (instance of UIController) to manage a console based user interface associated for this node application.
|
|
367
|
+
* @returns UIController instance to manage a console based user interface associated for this node application.
|
|
368
|
+
*/
|
|
369
|
+
GetUIController() {
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
get socketIoServerHelper() {
|
|
373
|
+
return __privateGet(this, _socketIoServerHelper);
|
|
374
|
+
}
|
|
375
|
+
set socketIoServerHelper(value) {
|
|
376
|
+
__privateSet(this, _socketIoServerHelper, value);
|
|
377
|
+
}
|
|
378
|
+
async TerminateDatabase() {
|
|
379
|
+
if (__privateGet(this, _accessLayer)) {
|
|
380
|
+
const logPrefix = `ProcessBase:TerminateDatabase():${process.pid}:`;
|
|
381
|
+
this.LogInfoMessage(`${logPrefix} Ending database connections and pools.`);
|
|
382
|
+
__privateGet(this, _accessLayer).off(dbaccess_js.IDBAccessLayerEvents.UpdateInstruments, __privateGet(this, _UpdatePGPoolManagerInstrument));
|
|
383
|
+
await __privateGet(this, _accessLayer).EndDatabase();
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
get accessLayer() {
|
|
387
|
+
if (this.options.useDatabase) {
|
|
388
|
+
if (__privateGet(this, _accessLayer) === null) {
|
|
389
|
+
__privateSet(this, _accessLayer, new dbaccess_js.DBAccessLayerManager().CreateAccessLayer({
|
|
390
|
+
accessLayerType: dbaccess_js.accessLayerType.postgresql,
|
|
391
|
+
accessLayerOptions: {
|
|
392
|
+
logger: this.options.logger,
|
|
393
|
+
usedefaultdb: false
|
|
394
|
+
}
|
|
395
|
+
}));
|
|
396
|
+
__privateGet(this, _accessLayer).on(dbaccess_js.IDBAccessLayerEvents.UpdateInstruments, __privateGet(this, _UpdatePGPoolManagerInstrument));
|
|
397
|
+
(async () => {
|
|
398
|
+
try {
|
|
399
|
+
const retVal = await this.accessLayer.GetResourceCount();
|
|
400
|
+
if (retVal.status !== index_js$1.StatusCodes.OK) {
|
|
401
|
+
this.LogInfoMessage(chalk.red(`Unable to get resources from the database. Is the database running? [${JSON.stringify(retVal)}]`));
|
|
402
|
+
} else {
|
|
403
|
+
this.LogInfoMessage(chalk.green(`Database connection successful. Resources: [${retVal.detail}]`));
|
|
404
|
+
}
|
|
405
|
+
} catch (error) {
|
|
406
|
+
this.LogInfoMessage(chalk.red(`Unable to get resources from the database. Is the database running? Error: [${error}]`));
|
|
407
|
+
}
|
|
408
|
+
})();
|
|
409
|
+
}
|
|
410
|
+
return __privateGet(this, _accessLayer);
|
|
411
|
+
}
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
emit(event, ...arg) {
|
|
415
|
+
super.emit(event, arg);
|
|
416
|
+
return this;
|
|
417
|
+
}
|
|
418
|
+
on(event, callback) {
|
|
419
|
+
super.on(event, callback);
|
|
420
|
+
return this;
|
|
421
|
+
}
|
|
422
|
+
off(event, callback) {
|
|
423
|
+
super.off(event, callback);
|
|
424
|
+
return this;
|
|
425
|
+
}
|
|
426
|
+
/*@@
|
|
427
|
+
get redisMessageHandler(): RedisMessageHandler {
|
|
428
|
+
return this.#redisMessageHandler as RedisMessageHandler;
|
|
429
|
+
}
|
|
430
|
+
*/
|
|
431
|
+
}
|
|
432
|
+
_options = new WeakMap();
|
|
433
|
+
_instrumentController = new WeakMap();
|
|
434
|
+
_systemInformationInterval = new WeakMap();
|
|
435
|
+
_socketIoServerHelper = new WeakMap();
|
|
436
|
+
_accessLayer = new WeakMap();
|
|
437
|
+
_ProcessBase_instances = new WeakSet();
|
|
438
|
+
GetFormattedLogMessage_fn = function(message) {
|
|
439
|
+
let prefix = "";
|
|
440
|
+
let col = null;
|
|
441
|
+
const appName = this.options.serviceName;
|
|
442
|
+
if (cluster.isPrimary) {
|
|
443
|
+
prefix = "M";
|
|
444
|
+
col = chalk.bold.cyan;
|
|
445
|
+
} else {
|
|
446
|
+
prefix = "W";
|
|
447
|
+
col = chalk.green;
|
|
448
|
+
}
|
|
449
|
+
return col(`${prefix}(${process.pid}) [${appName}]: ${message}`);
|
|
450
|
+
};
|
|
451
|
+
_UpdatePGPoolManagerInstrument = new WeakMap();
|
|
452
|
+
class STSTransportLoggerWinston extends Transport {
|
|
453
|
+
constructor(opts) {
|
|
454
|
+
super(opts);
|
|
455
|
+
__privateAdd(this, _options2);
|
|
456
|
+
__privateSet(this, _options2, opts);
|
|
457
|
+
}
|
|
458
|
+
log(info, callback) {
|
|
459
|
+
__privateGet(this, _options2).stsApp.LogMessageToLoggerInstrument(info.message);
|
|
460
|
+
this.emit("logged", info);
|
|
461
|
+
callback();
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
_options2 = new WeakMap();
|
|
465
|
+
class MasterProcessBase extends ProcessBase {
|
|
466
|
+
constructor(options) {
|
|
467
|
+
super(options);
|
|
468
|
+
__privateAdd(this, _MasterProcessBase_instances);
|
|
469
|
+
//static WORKER_MESSAGE_EVENT = 'sts_worker_message_event';
|
|
470
|
+
__privateAdd(this, _masterProcessExitTime, stsconfig_mjs.goptions.masterProcessExitTime);
|
|
471
|
+
__privateAdd(this, _childProcessExitTime, stsconfig_mjs.goptions.childProcessExitTime);
|
|
472
|
+
__privateAdd(this, _siValueObject, {
|
|
473
|
+
currentLoad: "currentLoad"
|
|
474
|
+
});
|
|
475
|
+
__privateAdd(this, _httpServer, null);
|
|
476
|
+
// Prometheus cluster server. See https://github.com/siimon/prom-client/blob/master/example/cluster.js
|
|
477
|
+
__privateAdd(this, _metricsServer, null);
|
|
478
|
+
__privateAdd(this, _aggregatorRegistry, null);
|
|
479
|
+
__privateAdd(this, _checkLatency, null);
|
|
480
|
+
__privateAdd(this, _killWorkers, {});
|
|
481
|
+
__privateAdd(this, _workers, 1);
|
|
482
|
+
// Start at 1 becuase of main thread
|
|
483
|
+
__privateAdd(this, _shuttingDown, false);
|
|
484
|
+
__privateAdd(this, _agentManager);
|
|
485
|
+
__privateAdd(this, _InitCluster, () => {
|
|
486
|
+
cluster.on("listening", (worker, address) => {
|
|
487
|
+
this.emit("clusterListening", worker, address);
|
|
488
|
+
let allListening = true;
|
|
489
|
+
for (const worker2 of Object.values(cluster.workers)) {
|
|
490
|
+
if (worker2 == null ? void 0 : worker2.isConnected) {
|
|
491
|
+
allListening = false;
|
|
492
|
+
break;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
if (allListening) {
|
|
496
|
+
this.LogInfoMessage(`Service instance started.`);
|
|
497
|
+
this.emit("allListening");
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
// https://github.com/siimon/prom-client/blob/master/example/cluster.js
|
|
502
|
+
__privateAdd(this, _SetupPrometheusForMaster, () => {
|
|
503
|
+
__privateSet(this, _metricsServer, express());
|
|
504
|
+
__privateSet(this, _aggregatorRegistry, new index_js$2.AggregatorRegistry());
|
|
505
|
+
switch (stsconfig_mjs.goptions.STSServerType) {
|
|
506
|
+
case "EXPRESS_TLS":
|
|
507
|
+
{
|
|
508
|
+
const options = {
|
|
509
|
+
key: fs.readFileSync(this.options.httpsServerKeyPath),
|
|
510
|
+
cert: fs.readFileSync(this.options.httpsServerCertificatePath)
|
|
511
|
+
};
|
|
512
|
+
__privateSet(this, _httpServer, node_https.createServer(options, __privateGet(this, _metricsServer)));
|
|
513
|
+
}
|
|
514
|
+
break;
|
|
515
|
+
case "EXPRESS": {
|
|
516
|
+
__privateSet(this, _httpServer, node_http.createServer(__privateGet(this, _metricsServer)));
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
__privateGet(this, _metricsServer).get("/cluster_metrics", async (req, res) => {
|
|
520
|
+
try {
|
|
521
|
+
const metrics = await __privateGet(this, _aggregatorRegistry).clusterMetrics();
|
|
522
|
+
res.set("Content-Type", __privateGet(this, _aggregatorRegistry).contentType);
|
|
523
|
+
res.send(metrics);
|
|
524
|
+
} catch (ex) {
|
|
525
|
+
res.statusCode = 500;
|
|
526
|
+
res.send(ex.message);
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
try {
|
|
530
|
+
__privateGet(this, _httpServer).listen(this.options.prometheusClusterPort, () => {
|
|
531
|
+
}).on("listening", () => {
|
|
532
|
+
this.emit(
|
|
533
|
+
"prometheusScrapesListening",
|
|
534
|
+
`${this.options.endpoint}:${this.options.prometheusClusterPort}/metrics`,
|
|
535
|
+
this.options.endpoint,
|
|
536
|
+
this.options.prometheusClusterPort
|
|
537
|
+
);
|
|
538
|
+
this.LogInfoMessage(`Prometheus scrapes ready and live on ${this.options.endpoint}:${this.options.prometheusClusterPort}/metrics`);
|
|
539
|
+
});
|
|
540
|
+
} catch (error) {
|
|
541
|
+
__privateMethod(this, _MasterProcessBase_instances, LogErrorMessage_fn).call(this, error);
|
|
542
|
+
throw error;
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
__privateAdd(this, _CheckLatency, async () => {
|
|
546
|
+
const start = process.hrtime();
|
|
547
|
+
await __privateGet(this, _GetLatency).call(this);
|
|
548
|
+
__privateGet(this, _LatencyRequestCompleted).call(this, start);
|
|
549
|
+
});
|
|
550
|
+
__privateAdd(this, _GetLatency, async () => {
|
|
551
|
+
let retVal = null;
|
|
552
|
+
const url = `${this.options.endpoint}:${this.options.port}${this.options.apiRoot}/latency`;
|
|
553
|
+
try {
|
|
554
|
+
retVal = await axios(new stsconfig_mjs.STSAxiosConfig(url, "get").withDefaultHeaders().withAgentManager(__privateGet(this, _agentManager)).config);
|
|
555
|
+
if (retVal.status !== 200) {
|
|
556
|
+
__privateMethod(this, _MasterProcessBase_instances, LogDebugMessage_fn).call(this, chalk.magenta(`Error (MasterProcessBase:#GetLatency): Invalid response from server: [${retVal.status}]`));
|
|
557
|
+
return null;
|
|
558
|
+
}
|
|
559
|
+
return retVal.data.detail;
|
|
560
|
+
} catch (error) {
|
|
561
|
+
__privateMethod(this, _MasterProcessBase_instances, LogDebugMessage_fn).call(this, chalk.red(`Error (MasterProcessBase:#GetLatency:catch): [${error}]`));
|
|
562
|
+
__privateMethod(this, _MasterProcessBase_instances, LogDebugMessage_fn).call(this, chalk.red(` url: [${url}]`));
|
|
563
|
+
if (error.response && error.response.data) {
|
|
564
|
+
__privateMethod(this, _MasterProcessBase_instances, LogDebugMessage_fn).call(this, chalk.red(` Details: [${JSON.stringify(error.response.data)}]`));
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
});
|
|
568
|
+
__privateAdd(this, _LatencyRequestCompleted, (start) => {
|
|
569
|
+
let timeInMs = 0;
|
|
570
|
+
const end = process.hrtime(start);
|
|
571
|
+
timeInMs = (end[0] * 1e9 + end[1]) / 1e6;
|
|
572
|
+
timeInMs = parseFloat(timeInMs.toFixed(4));
|
|
573
|
+
this.UpdateInstrument(stsobservability_mjs.Gauge.LATENCY_HISTOGRAM_GAUGE, {
|
|
574
|
+
val: timeInMs
|
|
575
|
+
});
|
|
576
|
+
this.UpdateInstrument(stsobservability_mjs.Gauge.LATENCY_GAUGE, {
|
|
577
|
+
val: timeInMs
|
|
578
|
+
});
|
|
579
|
+
});
|
|
580
|
+
__publicField(this, "SetupServer", async () => {
|
|
581
|
+
this.SetupInstrumentation();
|
|
582
|
+
setTimeout(() => {
|
|
583
|
+
this.SetupServerEx();
|
|
584
|
+
}, 100);
|
|
585
|
+
});
|
|
586
|
+
__privateAdd(this, __KillWorker, (id, signal, killProcess) => {
|
|
587
|
+
try {
|
|
588
|
+
if (cluster.workers && cluster.workers[id]) {
|
|
589
|
+
const worker = cluster.workers[id];
|
|
590
|
+
if (worker.process) {
|
|
591
|
+
this.LogInfoMessage(chalk.grey(`Sending terminate message `) + chalk.yellow(`(initiated by ${signal})`) + chalk.grey(` for worker PID: ${worker.process.pid}`));
|
|
592
|
+
const command = killProcess ? "TerminateAndKill" : "Terminate";
|
|
593
|
+
try {
|
|
594
|
+
worker.send({ command });
|
|
595
|
+
} catch (error) {
|
|
596
|
+
this.LogInfoMessage(chalk.red(`MasterProcessBase:#_KillWorker() (1): id: [${id}], signal: [${signal}], killProcess: [${killProcess}], error: [${error}]`));
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
599
|
+
return true;
|
|
600
|
+
} else {
|
|
601
|
+
this.LogInfoMessage(chalk.red(`MasterProcessBase:#_KillWorker(): Could not kill worker with id: [${id}]. The process does not exists`));
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
} else {
|
|
605
|
+
this.LogInfoMessage(chalk.red(`MasterProcessBase:#_KillWorker(): Could not kill worker with id: [${id}]. Worker does not exist within workers collection`));
|
|
606
|
+
return false;
|
|
607
|
+
}
|
|
608
|
+
} catch (error) {
|
|
609
|
+
this.LogInfoMessage(chalk.red(`MasterProcessBase:#_KillWorker() (2): id: [${id}], signal: [${signal}], killProcess: [${killProcess}], error: [${error}]`));
|
|
610
|
+
return false;
|
|
611
|
+
}
|
|
612
|
+
});
|
|
613
|
+
__publicField(this, "KillWorker", (id, signal = "SIGTERM", options, killProcess, allowKillAll) => {
|
|
614
|
+
try {
|
|
615
|
+
if (allowKillAll || Object.keys(cluster.workers).length > 1) {
|
|
616
|
+
if (id.localeCompare("0") === 0) {
|
|
617
|
+
const keys = Object.keys(cluster.workers);
|
|
618
|
+
for (let i = keys.length - 1; i > 0; i--) {
|
|
619
|
+
id = keys[i];
|
|
620
|
+
if (!__privateGet(this, _killWorkers)[id]) {
|
|
621
|
+
__privateGet(this, _killWorkers)[id] = id;
|
|
622
|
+
setTimeout(() => {
|
|
623
|
+
delete __privateGet(this, _killWorkers)[id];
|
|
624
|
+
}, 2e3).unref();
|
|
625
|
+
return __privateGet(this, __KillWorker).call(this, id, signal, killProcess);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
return false;
|
|
629
|
+
} else {
|
|
630
|
+
return __privateGet(this, __KillWorker).call(this, id, signal, killProcess);
|
|
631
|
+
}
|
|
632
|
+
} else {
|
|
633
|
+
this.LogInfoMessage(chalk.yellow(`MasterProcessBase:KillWorker(): Not allowed to kill the last worker process.`));
|
|
634
|
+
return false;
|
|
635
|
+
}
|
|
636
|
+
} catch (error) {
|
|
637
|
+
this.LogInfoMessage(chalk.red(`MasterProcessBase:KillWorker(): id: [${id}], signal: [${signal}], killProcess: [${killProcess}], error: [${error}]`));
|
|
638
|
+
return false;
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
__publicField(this, "KillWorkers", (signal, keepOne) => {
|
|
642
|
+
const logPrefix = `MasterProcessBase:KillWorkers():${process.pid}:`;
|
|
643
|
+
try {
|
|
644
|
+
this.LogInfoMessage(`${logPrefix} Killing Workers.`);
|
|
645
|
+
const keepOneAlive = keepOne ? keepOne : false;
|
|
646
|
+
let skippedFirst = false;
|
|
647
|
+
const sortedIdList = [];
|
|
648
|
+
for (const id in cluster.workers) {
|
|
649
|
+
sortedIdList.push(parseInt(id));
|
|
650
|
+
}
|
|
651
|
+
sortedIdList.sort().forEach((id) => {
|
|
652
|
+
if (keepOneAlive && !skippedFirst) {
|
|
653
|
+
skippedFirst = true;
|
|
654
|
+
} else {
|
|
655
|
+
this.KillWorker(id.toString(), signal, null, false, true);
|
|
656
|
+
}
|
|
657
|
+
});
|
|
658
|
+
} catch (error) {
|
|
659
|
+
this.LogInfoMessage(chalk.red(`${logPrefix} signal: [${signal}], keepOne: [${keepOne}], error: [${error}]`));
|
|
660
|
+
}
|
|
661
|
+
});
|
|
662
|
+
__privateAdd(this, _UpdateWorkersInstrument, () => {
|
|
663
|
+
setTimeout(() => {
|
|
664
|
+
this.UpdateInstrument(stsobservability_mjs.Gauge.CORE_COUNT_GAUGE, {
|
|
665
|
+
val: __privateGet(this, _workers)
|
|
666
|
+
});
|
|
667
|
+
}, 2e3);
|
|
668
|
+
});
|
|
669
|
+
__publicField(this, "IncWorkers", () => {
|
|
670
|
+
__privateWrapper(this, _workers)._++;
|
|
671
|
+
__privateMethod(this, _MasterProcessBase_instances, LogDebugMessage_fn).call(this, ` Inc Workers. Total thread count: [${__privateGet(this, _workers)}]`);
|
|
672
|
+
__privateGet(this, _UpdateWorkersInstrument).call(this);
|
|
673
|
+
});
|
|
674
|
+
__publicField(this, "DecWorkers", () => {
|
|
675
|
+
__privateWrapper(this, _workers)._--;
|
|
676
|
+
__privateMethod(this, _MasterProcessBase_instances, LogDebugMessage_fn).call(this, ` Dec Workers. Total thread count: [${__privateGet(this, _workers)}]`);
|
|
677
|
+
__privateGet(this, _UpdateWorkersInstrument).call(this);
|
|
678
|
+
});
|
|
679
|
+
__publicField(this, "AddWorker", (options) => {
|
|
680
|
+
const workerId = __privateGet(this, _SpawnWorker).call(this, options);
|
|
681
|
+
__privateMethod(this, _MasterProcessBase_instances, LogDebugMessage_fn).call(this, chalk.yellow(` Spawned worker with id: [${workerId}]`));
|
|
682
|
+
if (options) {
|
|
683
|
+
__privateMethod(this, _MasterProcessBase_instances, LogDebugMessage_fn).call(this, chalk.yellow(` Options: [${JSON.stringify(options)}]`));
|
|
684
|
+
}
|
|
685
|
+
return workerId;
|
|
686
|
+
});
|
|
687
|
+
__privateAdd(this, _processIPCCommand, async (iPCMessagePayload) => {
|
|
688
|
+
var _a, _b, _c;
|
|
689
|
+
__privateMethod(this, _MasterProcessBase_instances, LogDebugMessage_fn).call(this, chalk.yellow(` Processing message command: [${iPCMessagePayload.command}]`));
|
|
690
|
+
switch (iPCMessagePayload.command) {
|
|
691
|
+
case IPCMessageCommand.AddWorker: {
|
|
692
|
+
const workerId = this.AddWorker((_a = iPCMessagePayload.requestDetail) == null ? void 0 : _a.options);
|
|
693
|
+
iPCMessagePayload.responseDetail = {
|
|
694
|
+
workerId
|
|
695
|
+
};
|
|
696
|
+
return iPCMessagePayload;
|
|
697
|
+
}
|
|
698
|
+
case IPCMessageCommand.DeleteWorker: {
|
|
699
|
+
const workerId = (_b = iPCMessagePayload.requestDetail) == null ? void 0 : _b.workerId;
|
|
700
|
+
const workerKilled = this.KillWorker(workerId, "SIGTERM", (_c = iPCMessagePayload.requestDetail) == null ? void 0 : _c.options, true, false);
|
|
701
|
+
__privateMethod(this, _MasterProcessBase_instances, LogDebugMessage_fn).call(this, chalk.yellow(` Killed worker with id: [${workerId}]`));
|
|
702
|
+
iPCMessagePayload.responseDetail = {
|
|
703
|
+
workerId,
|
|
704
|
+
workerKilled
|
|
705
|
+
};
|
|
706
|
+
return iPCMessagePayload;
|
|
707
|
+
}
|
|
708
|
+
case IPCMessageCommand.GetConfig: {
|
|
709
|
+
const safeOptions = { ...this.options };
|
|
710
|
+
delete safeOptions.logger;
|
|
711
|
+
delete safeOptions.publisherLogger;
|
|
712
|
+
delete safeOptions.expressServerRouteFactory;
|
|
713
|
+
iPCMessagePayload.responseDetail = {
|
|
714
|
+
safeOptions
|
|
715
|
+
};
|
|
716
|
+
return iPCMessagePayload;
|
|
717
|
+
}
|
|
718
|
+
default: {
|
|
719
|
+
const errorMessage = `Could not process command: [${iPCMessagePayload.command}].`;
|
|
720
|
+
__privateMethod(this, _MasterProcessBase_instances, LogDebugMessage_fn).call(this, chalk.red(` ${errorMessage}`));
|
|
721
|
+
throw new Error(errorMessage);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
__privateAdd(this, _SpawnWorker, (spawnWorkerOptions) => {
|
|
726
|
+
const workerEnv = {};
|
|
727
|
+
const tempOptions = { ...this.options };
|
|
728
|
+
delete tempOptions.logger;
|
|
729
|
+
delete tempOptions.publisherLogger;
|
|
730
|
+
workerEnv["STS_GSD_SII"] = JSON.stringify(tempOptions);
|
|
731
|
+
if (spawnWorkerOptions) {
|
|
732
|
+
workerEnv["STS_GSD_OPTIONS"] = JSON.stringify(spawnWorkerOptions);
|
|
733
|
+
}
|
|
734
|
+
if (this.options.workerExec) {
|
|
735
|
+
cluster.setupPrimary({
|
|
736
|
+
exec: this.options.workerExec,
|
|
737
|
+
silent: true
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
const worker = cluster.fork(workerEnv);
|
|
741
|
+
this.IncWorkers();
|
|
742
|
+
worker.on("exit", (code, signal) => {
|
|
743
|
+
this.emit("workerExit", code, signal);
|
|
744
|
+
if (signal) {
|
|
745
|
+
this.LogInfoMessage(`Worker: ${worker.process.pid} was killed by signal: ${signal}`);
|
|
746
|
+
} else if (code !== 0) {
|
|
747
|
+
this.LogInfoMessage(`Worker: ${worker.process.pid} exited with error code: ${code}`);
|
|
748
|
+
} else {
|
|
749
|
+
this.LogInfoMessage(`Worker: ${worker.process.pid} exited successfully, code: ${code}, signal: ${signal}`);
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
worker.on("message", async (payload) => {
|
|
753
|
+
this.emit("workerMessage", worker.id, payload);
|
|
754
|
+
if (payload.requestResponse) {
|
|
755
|
+
const iPCMessagePayload = payload;
|
|
756
|
+
const response = await this.ProcessIPCCommand(iPCMessagePayload);
|
|
757
|
+
worker.send(response);
|
|
758
|
+
} else {
|
|
759
|
+
__privateMethod(this, _MasterProcessBase_instances, WorkerMessageEvent_fn).call(this, worker.id, payload);
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
worker.on("error", (error) => {
|
|
763
|
+
this.emit("workerError", error);
|
|
764
|
+
const message = chalk.red(`#SpawnWorker():worker.on('error'): Error: [${error}]`);
|
|
765
|
+
this.LogErrorMessage(message);
|
|
766
|
+
});
|
|
767
|
+
this.emit("workerAdded", worker.id);
|
|
768
|
+
return worker.id;
|
|
769
|
+
});
|
|
770
|
+
__publicField(this, "SetupServerEx", async () => {
|
|
771
|
+
this.ProcessStartup();
|
|
772
|
+
this.LogInfoMessage(`Service instance starting. Instance Id: [${this.options.serviceInstanceId}]`);
|
|
773
|
+
this.LogSystemTelemetry();
|
|
774
|
+
if (this.options.wssServer === true) {
|
|
775
|
+
if (this.options.useSocketIoRedisAdaptor) {
|
|
776
|
+
this.LogInfoMessage(`Using Redis for socket.io cluster management (master)`);
|
|
777
|
+
} else {
|
|
778
|
+
this.LogInfoMessage(`Using nodejs cluster mode for socket.io cluster management`);
|
|
779
|
+
index_js$3.setupPrimary();
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
if (this.options.prometheusSupport === true) {
|
|
783
|
+
__privateGet(this, _SetupPrometheusForMaster).call(this);
|
|
784
|
+
}
|
|
785
|
+
const numCPUs = await this.GetNumCPUs();
|
|
786
|
+
for (let i = 0; i < numCPUs; i++) {
|
|
787
|
+
__privateGet(this, _SpawnWorker).call(this);
|
|
788
|
+
}
|
|
789
|
+
__privateGet(this, _InitCluster).call(this);
|
|
790
|
+
cluster.on("listening", (worker, address) => {
|
|
791
|
+
this.emit("clusterListening", worker, address);
|
|
792
|
+
this.LogInfoMessage(`Worker process ${worker.process.pid} is listening at address: ${JSON.stringify(address)}`);
|
|
793
|
+
});
|
|
794
|
+
cluster.on("online", (worker) => {
|
|
795
|
+
this.emit("clusterOnline", worker);
|
|
796
|
+
this.LogInfoMessage(`Worker process ${worker.process.pid} is online`);
|
|
797
|
+
});
|
|
798
|
+
cluster.on("exit", (worker, code, signal) => {
|
|
799
|
+
this.emit("clusterExit", worker, code, signal);
|
|
800
|
+
if (code !== null && code === 0 || signal === "SIGINT") {
|
|
801
|
+
this.LogInfoMessage(chalk.green(`Process ${worker.process.pid} terminated gracefully with code: ${code}, signal: ${signal}`));
|
|
802
|
+
this.DecWorkers();
|
|
803
|
+
} else if (code !== null && code === 15 || signal === "SIGTERM") {
|
|
804
|
+
this.DecWorkers();
|
|
805
|
+
this.LogInfoMessage(chalk.red(`Process ${worker.process.pid} terminated with code: ${code}, signal: ${signal}`));
|
|
806
|
+
} else {
|
|
807
|
+
this.DecWorkers();
|
|
808
|
+
this.LogInfoMessage(chalk.red(`worker ${worker.process.pid} died`));
|
|
809
|
+
this.LogInfoMessage(chalk.red(`code: ${code}`));
|
|
810
|
+
this.LogInfoMessage(chalk.red(`signal: ${signal}`));
|
|
811
|
+
this.LogInfoMessage(chalk.red("process terminated in an error state"));
|
|
812
|
+
if (stsconfig_mjs.goptions.respawnOnFail === true) {
|
|
813
|
+
this.LogInfoMessage(chalk.magenta(`Attemping to respawn worker`));
|
|
814
|
+
__privateGet(this, _SpawnWorker).call(this);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
const TerminateLatency = () => {
|
|
819
|
+
if (__privateGet(this, _checkLatency)) {
|
|
820
|
+
clearInterval(__privateGet(this, _checkLatency));
|
|
821
|
+
__privateSet(this, _checkLatency, null);
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
const TerminateHTTPServer = async () => {
|
|
825
|
+
if (__privateGet(this, _httpServer) !== null) {
|
|
826
|
+
const logPrefix = `ServerProcessBase:TerminateHTTPServer():${process.pid}:`;
|
|
827
|
+
this.LogInfoMessage(`${logPrefix} Closing httpServer.`);
|
|
828
|
+
await __privateGet(this, _httpServer).close();
|
|
829
|
+
__privateSet(this, _httpServer, null);
|
|
830
|
+
}
|
|
831
|
+
};
|
|
832
|
+
const Terminate = async (signal) => {
|
|
833
|
+
const logPrefix = `MasterProcessBase:Terminate():${process.pid}:`;
|
|
834
|
+
if (__privateGet(this, _shuttingDown) === false) {
|
|
835
|
+
__privateSet(this, _shuttingDown, true);
|
|
836
|
+
if (signal) {
|
|
837
|
+
this.LogInfoMessage(this.GetSignalColour(signal)(`${logPrefix} Received signal: ${signal}`));
|
|
838
|
+
} else {
|
|
839
|
+
this.LogInfoMessage(this.GetSignalColour(null)(`${logPrefix} Received Terminate without signal.`));
|
|
840
|
+
}
|
|
841
|
+
TerminateLatency();
|
|
842
|
+
await this.ProcessTerminate();
|
|
843
|
+
this.TerminateUIController();
|
|
844
|
+
this.LogInfoMessage(`${logPrefix} De-Registering service.`);
|
|
845
|
+
await TerminateHTTPServer();
|
|
846
|
+
this.KillWorkers(signal);
|
|
847
|
+
await this.TerminateDatabase();
|
|
848
|
+
this.TerminateInstrumentController();
|
|
849
|
+
await stsutils.Sleep(1e3);
|
|
850
|
+
this.ProcessExit(__privateGet(this, _childProcessExitTime) + __privateGet(this, _masterProcessExitTime));
|
|
851
|
+
} else {
|
|
852
|
+
this.LogInfoMessage(`${logPrefix} Process already terminating.`);
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
process.on("SIGINT", async () => {
|
|
856
|
+
this.emit("processSigint");
|
|
857
|
+
await Terminate("SIGINT");
|
|
858
|
+
});
|
|
859
|
+
process.on("SIGTERM", async () => {
|
|
860
|
+
this.emit("processSigterm");
|
|
861
|
+
await Terminate("SIGTERM");
|
|
862
|
+
});
|
|
863
|
+
process.on("exit", (code) => {
|
|
864
|
+
this.emit("processExit", code);
|
|
865
|
+
if (code === 0) {
|
|
866
|
+
this.LogInfoMessage(chalk.green(`Main Process: ${process.pid} terminated gracefully with code: ${code}`));
|
|
867
|
+
} else {
|
|
868
|
+
this.LogInfoMessage(chalk.red(`Main Process: ${process.pid} terminated with code: ${code}`));
|
|
869
|
+
}
|
|
870
|
+
});
|
|
871
|
+
if (this.options.useLatency) {
|
|
872
|
+
__privateSet(this, _checkLatency, setInterval(() => {
|
|
873
|
+
__privateGet(this, _CheckLatency).call(this);
|
|
874
|
+
}, 1e3).unref());
|
|
875
|
+
}
|
|
876
|
+
this.MasterStarted();
|
|
877
|
+
this.LogInfoMessage(chalk.green(`Master process:${process.pid} started`));
|
|
878
|
+
});
|
|
879
|
+
__publicField(this, "BroadcastDataToWorkers", (command, data) => {
|
|
880
|
+
try {
|
|
881
|
+
for (const id in cluster.workers) {
|
|
882
|
+
try {
|
|
883
|
+
cluster.workers[id].process.send({ command, data });
|
|
884
|
+
} catch (error) {
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
} catch (error) {
|
|
888
|
+
}
|
|
889
|
+
});
|
|
890
|
+
__privateSet(this, _agentManager, new stsconfig_mjs.AgentManager({
|
|
891
|
+
agentOptions: {
|
|
892
|
+
keepAlive: false,
|
|
893
|
+
// Use basic defaults. This agent will not use keep-alive.
|
|
894
|
+
maxFreeSockets: stsconfig_mjs.goptions.maxFreeSockets,
|
|
895
|
+
maxSockets: stsconfig_mjs.goptions.maxSockets,
|
|
896
|
+
maxTotalSockets: stsconfig_mjs.goptions.maxTotalSockets,
|
|
897
|
+
timeout: stsconfig_mjs.goptions.timeout,
|
|
898
|
+
rejectUnauthorized: stsconfig_mjs.goptions.isProduction
|
|
899
|
+
// Allows self-signed certificates if non-production
|
|
900
|
+
}
|
|
901
|
+
}));
|
|
902
|
+
}
|
|
903
|
+
CollectAdditionalTelemetry() {
|
|
904
|
+
si.get(__privateGet(this, _siValueObject)).then((data) => {
|
|
905
|
+
this.UpdateInstrument(stsobservability_mjs.Gauge.CPU_SYSTEM_LOAD_GAUGE, {
|
|
906
|
+
val: data.currentLoad.currentLoad
|
|
907
|
+
});
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
GetAdditionalInstruments() {
|
|
911
|
+
return [
|
|
912
|
+
[stsobservability_mjs.Gauge.CPU_SYSTEM_LOAD_GAUGE, stsobservability_mjs.GaugeTypes.INSTRUMENT_GAUGE, {
|
|
913
|
+
interval: stsconfig_mjs.goptions.instrumentationObservationInterval,
|
|
914
|
+
sampleSize: stsconfig_mjs.goptions.instrumentationTimeWindow
|
|
915
|
+
}]
|
|
916
|
+
];
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Note: msg removed from signature but will be passed at run-time.
|
|
920
|
+
* @param {*} msg
|
|
921
|
+
*/
|
|
922
|
+
WorkerMessageEvent(workerId, msg) {
|
|
923
|
+
return null;
|
|
924
|
+
}
|
|
925
|
+
async ProcessIPCCommand(iPCMessagePayload) {
|
|
926
|
+
return __privateGet(this, _processIPCCommand).call(this, iPCMessagePayload);
|
|
927
|
+
}
|
|
928
|
+
MasterStarted() {
|
|
929
|
+
const transport = new STSTransportLoggerWinston({
|
|
930
|
+
stsApp: this
|
|
931
|
+
});
|
|
932
|
+
setTimeout(() => {
|
|
933
|
+
this.options.logger.add(transport);
|
|
934
|
+
}, 0);
|
|
935
|
+
}
|
|
936
|
+
get shuttingDown() {
|
|
937
|
+
return __privateGet(this, _shuttingDown);
|
|
938
|
+
}
|
|
939
|
+
/*
|
|
940
|
+
#GetSystemInformation = async (): Promise<JSONObject> => {
|
|
941
|
+
// https://systeminformation.io/
|
|
942
|
+
const valueObject = {
|
|
943
|
+
system: '*',
|
|
944
|
+
osInfo: '*',
|
|
945
|
+
cpu: '*',
|
|
946
|
+
mem: '*',
|
|
947
|
+
dockerInfo: '*',
|
|
948
|
+
//dockerImages: '*',
|
|
949
|
+
dockerContainers: '*',
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
const sysinfo = await si.get(valueObject);
|
|
953
|
+
const numCPUs = await this.GetNumCPUs();
|
|
954
|
+
const hostname = sysinfo.osInfo.hostname;
|
|
955
|
+
|
|
956
|
+
const hostaddr = GetFirstNetworkInterface();
|
|
957
|
+
|
|
958
|
+
const promArray: Promise<any>[] = [ ];
|
|
959
|
+
|
|
960
|
+
sysinfo.dockerContainers.forEach((dc: { id: string; }) => {
|
|
961
|
+
const dcs = promArray.push(si.dockerContainerStats(dc.id));
|
|
962
|
+
console.log(dcs);
|
|
963
|
+
});
|
|
964
|
+
const dockerContainerStats = await Promise.all(promArray);
|
|
965
|
+
|
|
966
|
+
const sysInfo = {
|
|
967
|
+
serviceProcessContext: this.options.serviceProcessContext,
|
|
968
|
+
hostname,
|
|
969
|
+
numCPUs,
|
|
970
|
+
hostaddr,
|
|
971
|
+
system: sysinfo.system,
|
|
972
|
+
osInfo: sysinfo.osInfo,
|
|
973
|
+
cpu: sysinfo.cpu,
|
|
974
|
+
mem: sysinfo.mem,
|
|
975
|
+
dockerInfo: sysinfo.dockerInfo,
|
|
976
|
+
//dockerImages: sysinfo.dockerImages,
|
|
977
|
+
dockerContainers: sysinfo.dockerContainers,
|
|
978
|
+
dockerContainerStats
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
return sysInfo;
|
|
982
|
+
}
|
|
983
|
+
*/
|
|
984
|
+
}
|
|
985
|
+
_masterProcessExitTime = new WeakMap();
|
|
986
|
+
_childProcessExitTime = new WeakMap();
|
|
987
|
+
_siValueObject = new WeakMap();
|
|
988
|
+
_httpServer = new WeakMap();
|
|
989
|
+
_metricsServer = new WeakMap();
|
|
990
|
+
_aggregatorRegistry = new WeakMap();
|
|
991
|
+
_checkLatency = new WeakMap();
|
|
992
|
+
_killWorkers = new WeakMap();
|
|
993
|
+
_workers = new WeakMap();
|
|
994
|
+
_shuttingDown = new WeakMap();
|
|
995
|
+
_agentManager = new WeakMap();
|
|
996
|
+
_MasterProcessBase_instances = new WeakSet();
|
|
997
|
+
LogErrorMessage_fn = function(message) {
|
|
998
|
+
this.options.logger.error(message);
|
|
999
|
+
};
|
|
1000
|
+
LogDebugMessage_fn = function(message) {
|
|
1001
|
+
this.options.logger.debug(message);
|
|
1002
|
+
};
|
|
1003
|
+
WorkerMessageEvent_fn = function(workerId, msg) {
|
|
1004
|
+
if (msg.command) {
|
|
1005
|
+
this.WorkerMessageEvent(workerId, msg);
|
|
1006
|
+
}
|
|
1007
|
+
};
|
|
1008
|
+
_InitCluster = new WeakMap();
|
|
1009
|
+
_SetupPrometheusForMaster = new WeakMap();
|
|
1010
|
+
_CheckLatency = new WeakMap();
|
|
1011
|
+
_GetLatency = new WeakMap();
|
|
1012
|
+
_LatencyRequestCompleted = new WeakMap();
|
|
1013
|
+
__KillWorker = new WeakMap();
|
|
1014
|
+
_UpdateWorkersInstrument = new WeakMap();
|
|
1015
|
+
_processIPCCommand = new WeakMap();
|
|
1016
|
+
_SpawnWorker = new WeakMap();
|
|
1017
|
+
var ServerNetworkMiddlewareEventName = /* @__PURE__ */ ((ServerNetworkMiddlewareEventName2) => {
|
|
1018
|
+
ServerNetworkMiddlewareEventName2["UpdateInstrument_SERVER_NET_VAL"] = "UpdateInstrument_SERVER_NET_VAL";
|
|
1019
|
+
return ServerNetworkMiddlewareEventName2;
|
|
1020
|
+
})(ServerNetworkMiddlewareEventName || {});
|
|
1021
|
+
class ServerNetworkMiddleware extends stsutils.STSOptionsBase {
|
|
1022
|
+
constructor(options) {
|
|
1023
|
+
super(options);
|
|
1024
|
+
__privateAdd(this, _ServerNetworkMiddleware_instances);
|
|
1025
|
+
__privateAdd(this, _tinyEmitter, new index_js.TinyEmitter());
|
|
1026
|
+
__privateAdd(this, _socketCollection, {});
|
|
1027
|
+
__privateAdd(this, _id, "");
|
|
1028
|
+
__publicField(this, "GetSocketRecord", (socket) => {
|
|
1029
|
+
for (const [, socketRecord] of Object.entries(__privateGet(this, _socketCollection))) {
|
|
1030
|
+
if (socketRecord.socket === socket) {
|
|
1031
|
+
return socketRecord;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
return null;
|
|
1035
|
+
});
|
|
1036
|
+
__publicField(this, "UpdateNetworkStats", (workingSocketRecord, eventName, req) => {
|
|
1037
|
+
workingSocketRecord.originalUrl = req.originalUrl;
|
|
1038
|
+
workingSocketRecord.eventName = eventName;
|
|
1039
|
+
workingSocketRecord.currentBytesRead = req.socket.bytesRead;
|
|
1040
|
+
workingSocketRecord.currentBytesWritten = req.socket.bytesWritten;
|
|
1041
|
+
workingSocketRecord.requestBytesRead = workingSocketRecord.currentBytesRead - workingSocketRecord.lastBytesRead;
|
|
1042
|
+
workingSocketRecord.requestBytesWritten = workingSocketRecord.currentBytesWritten - workingSocketRecord.lastBytesWritten;
|
|
1043
|
+
const workingSocketEventRecord = { ...workingSocketRecord };
|
|
1044
|
+
delete workingSocketEventRecord.socket;
|
|
1045
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.gray(`Sending event: [${JSON.stringify(workingSocketEventRecord)}]`));
|
|
1046
|
+
__privateGet(this, _tinyEmitter).emit("UpdateInstrument_SERVER_NET_VAL", workingSocketEventRecord);
|
|
1047
|
+
workingSocketRecord.lastBytesRead = workingSocketRecord.currentBytesRead;
|
|
1048
|
+
workingSocketRecord.lastBytesWritten = workingSocketRecord.currentBytesWritten;
|
|
1049
|
+
});
|
|
1050
|
+
__privateAdd(this, _GetRequestContentSize, (req) => {
|
|
1051
|
+
try {
|
|
1052
|
+
let contentLength = 0;
|
|
1053
|
+
if (req["_contentLength"]) {
|
|
1054
|
+
contentLength = req["_contentLength"];
|
|
1055
|
+
} else {
|
|
1056
|
+
if (req.headers["content-length"]) {
|
|
1057
|
+
contentLength = parseInt(req.headers["content-length"]);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
return contentLength;
|
|
1061
|
+
} catch (error) {
|
|
1062
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogErrorMessage_fn2).call(this, chalk.red(`ServerNetworkMiddleware:#GetRequestContentSize(): Error: [${error}]`));
|
|
1063
|
+
return 0;
|
|
1064
|
+
}
|
|
1065
|
+
});
|
|
1066
|
+
__publicField(this, "Middleware", (req, res, next) => {
|
|
1067
|
+
let workingSocketRecord = null;
|
|
1068
|
+
workingSocketRecord = this.GetSocketRecord(req.socket);
|
|
1069
|
+
if (!workingSocketRecord) {
|
|
1070
|
+
__privateSet(this, _id, index_js$4.v4());
|
|
1071
|
+
workingSocketRecord = {
|
|
1072
|
+
id: `${this.options.name}_${__privateGet(this, _id).toString()}`,
|
|
1073
|
+
socket: req.socket,
|
|
1074
|
+
currentBytesRead: 0,
|
|
1075
|
+
currentBytesWritten: 0,
|
|
1076
|
+
lastBytesRead: 0,
|
|
1077
|
+
lastBytesWritten: 0,
|
|
1078
|
+
requestBytesRead: 0,
|
|
1079
|
+
requestBytesWritten: 0,
|
|
1080
|
+
originalUrl: req.originalUrl,
|
|
1081
|
+
eventName: ""
|
|
1082
|
+
};
|
|
1083
|
+
__privateGet(this, _socketCollection)[workingSocketRecord.id] = workingSocketRecord;
|
|
1084
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.gray(`Adding new socket to recordset: ID: [${workingSocketRecord.id}], originalUrl: [${workingSocketRecord.originalUrl}]`));
|
|
1085
|
+
workingSocketRecord.socket.on("data", () => {
|
|
1086
|
+
const socketRecord = this.GetSocketRecord(workingSocketRecord.socket);
|
|
1087
|
+
if (socketRecord) {
|
|
1088
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.gray(`Socket data event: ID: [${socketRecord.id}], originalUrl: [${socketRecord.originalUrl}]`));
|
|
1089
|
+
this.UpdateNetworkStats(socketRecord, "socket_data", req);
|
|
1090
|
+
} else {
|
|
1091
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.magenta(`Socket data event: Could not find socket within recordset`));
|
|
1092
|
+
}
|
|
1093
|
+
});
|
|
1094
|
+
workingSocketRecord.socket.on("close", () => {
|
|
1095
|
+
const socketRecord = this.GetSocketRecord(workingSocketRecord.socket);
|
|
1096
|
+
if (socketRecord) {
|
|
1097
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.gray(`Socket close event: ID: [${socketRecord.id}], originalUrl: [${socketRecord.originalUrl}]`));
|
|
1098
|
+
this.UpdateNetworkStats(socketRecord, "socket_close", req);
|
|
1099
|
+
delete __privateGet(this, _socketCollection)[socketRecord.id];
|
|
1100
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.gray(`Socket removed from recordset: ID: [${socketRecord.id}], originalUrl: [${socketRecord.originalUrl}]`));
|
|
1101
|
+
} else {
|
|
1102
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.magenta(`Socket close event: Could not find socket within recordset`));
|
|
1103
|
+
}
|
|
1104
|
+
});
|
|
1105
|
+
workingSocketRecord.socket.on("end", () => {
|
|
1106
|
+
const socketRecord = this.GetSocketRecord(workingSocketRecord.socket);
|
|
1107
|
+
if (socketRecord) {
|
|
1108
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.gray(`Socket end event: ID: [${socketRecord.id}], originalUrl: [${socketRecord.originalUrl}]`));
|
|
1109
|
+
this.UpdateNetworkStats(socketRecord, "socket_end", req);
|
|
1110
|
+
} else {
|
|
1111
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.magenta(`Socket end event: Could not find socket within recordset`));
|
|
1112
|
+
}
|
|
1113
|
+
});
|
|
1114
|
+
}
|
|
1115
|
+
onHeaders(res, () => {
|
|
1116
|
+
let contentLength = 0;
|
|
1117
|
+
if (res["_contentLength"]) {
|
|
1118
|
+
contentLength = res["_contentLength"];
|
|
1119
|
+
} else {
|
|
1120
|
+
if (res.hasHeader("content-length")) {
|
|
1121
|
+
contentLength = parseInt(res.getHeader("content-length"));
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
1125
|
+
res.setHeader("Pragma", "no-cache");
|
|
1126
|
+
res.setHeader("Expires", "0");
|
|
1127
|
+
const headerLength = JSON.stringify(res.getHeaders()).length;
|
|
1128
|
+
const totalSize = contentLength + headerLength;
|
|
1129
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.white.bgBlue(`contentLength: [${contentLength}], headerLength: [${headerLength}], total Size: [${totalSize}]`));
|
|
1130
|
+
});
|
|
1131
|
+
req.on("end", () => {
|
|
1132
|
+
const socketRecord = this.GetSocketRecord(req.socket);
|
|
1133
|
+
if (socketRecord) {
|
|
1134
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.gray(`Request end event: ID: [${socketRecord.id}], originalUrl: [${socketRecord.originalUrl}]`));
|
|
1135
|
+
this.UpdateNetworkStats(socketRecord, "req_end", req);
|
|
1136
|
+
} else {
|
|
1137
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.magenta(`Request end event: Could not find socket within recordset`));
|
|
1138
|
+
}
|
|
1139
|
+
});
|
|
1140
|
+
req.on("close", () => {
|
|
1141
|
+
const socketRecord = this.GetSocketRecord(req.socket);
|
|
1142
|
+
if (socketRecord) {
|
|
1143
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.gray(`Request close event: ID: [${socketRecord.id}], originalUrl: [${socketRecord.originalUrl}]`));
|
|
1144
|
+
this.UpdateNetworkStats(socketRecord, "req_close", req);
|
|
1145
|
+
} else {
|
|
1146
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.magenta(`Request close event: Could not find socket within recordset`));
|
|
1147
|
+
}
|
|
1148
|
+
});
|
|
1149
|
+
const inHeadersLength = JSON.stringify(req.headers).length;
|
|
1150
|
+
const inContentLength = __privateGet(this, _GetRequestContentSize).call(this, req);
|
|
1151
|
+
const inTotal = inHeadersLength + inContentLength;
|
|
1152
|
+
__privateMethod(this, _ServerNetworkMiddleware_instances, LogSillyMessage_fn).call(this, chalk.white.bgGray(`inHeadersLength: [${inHeadersLength}], inContentLength: [${inContentLength}], inTotal: [${inTotal}]`));
|
|
1153
|
+
this.UpdateNetworkStats(workingSocketRecord, "middleware", req);
|
|
1154
|
+
next();
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1157
|
+
on(eventName, callBackFn) {
|
|
1158
|
+
__privateGet(this, _tinyEmitter).on(eventName, callBackFn);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
_tinyEmitter = new WeakMap();
|
|
1162
|
+
_socketCollection = new WeakMap();
|
|
1163
|
+
_id = new WeakMap();
|
|
1164
|
+
_ServerNetworkMiddleware_instances = new WeakSet();
|
|
1165
|
+
LogSillyMessage_fn = function(message) {
|
|
1166
|
+
var _a;
|
|
1167
|
+
(_a = this.options) == null ? void 0 : _a.logger.silly(message);
|
|
1168
|
+
};
|
|
1169
|
+
LogErrorMessage_fn2 = function(message) {
|
|
1170
|
+
var _a;
|
|
1171
|
+
(_a = this.options) == null ? void 0 : _a.logger.error(message);
|
|
1172
|
+
};
|
|
1173
|
+
_GetRequestContentSize = new WeakMap();
|
|
1174
|
+
class STSExpressServer {
|
|
1175
|
+
constructor(options, stsApp) {
|
|
1176
|
+
__privateAdd(this, _app);
|
|
1177
|
+
var _a;
|
|
1178
|
+
const requestLoggerMiddleware = new stsobservability_mjs.RequestLoggerMiddleware({
|
|
1179
|
+
ignoresocketio: stsconfig_mjs.goptions.ignoresocketio
|
|
1180
|
+
});
|
|
1181
|
+
const serverNetworkMiddleware = new ServerNetworkMiddleware({
|
|
1182
|
+
name: stsApp.options.serviceName,
|
|
1183
|
+
outputDebug: false,
|
|
1184
|
+
logger: (_a = stsApp.options) == null ? void 0 : _a.logger
|
|
1185
|
+
});
|
|
1186
|
+
serverNetworkMiddleware.on(ServerNetworkMiddlewareEventName.UpdateInstrument_SERVER_NET_VAL, (data) => {
|
|
1187
|
+
stsApp.UpdateInstrument(stsobservability_mjs.Gauge.NETWORK_RX_GAUGE, {
|
|
1188
|
+
Inc: data.requestBytesRead
|
|
1189
|
+
});
|
|
1190
|
+
stsApp.UpdateInstrument(stsobservability_mjs.Gauge.NETWORK_TX_GAUGE, {
|
|
1191
|
+
Inc: data.requestBytesWritten
|
|
1192
|
+
});
|
|
1193
|
+
});
|
|
1194
|
+
requestLoggerMiddleware.on(stsobservability_mjs.RequestLoggerMiddlewareEventName.UpdateInstrument_AR_INC, () => {
|
|
1195
|
+
stsApp.UpdateInstrument(stsobservability_mjs.Gauge.ACTIVE_REQUEST_GAUGE, {
|
|
1196
|
+
Inc: 1
|
|
1197
|
+
});
|
|
1198
|
+
});
|
|
1199
|
+
requestLoggerMiddleware.on(stsobservability_mjs.RequestLoggerMiddlewareEventName.UpdateInstrument_AR_DEC, () => {
|
|
1200
|
+
stsApp.UpdateInstrument(stsobservability_mjs.Gauge.ACTIVE_REQUEST_GAUGE, {
|
|
1201
|
+
Dec: 1
|
|
1202
|
+
});
|
|
1203
|
+
});
|
|
1204
|
+
requestLoggerMiddleware.on(stsobservability_mjs.RequestLoggerMiddlewareEventName.UpdateInstrument_DH_VAL, (timeInMs) => {
|
|
1205
|
+
stsApp.UpdateInstrument(stsobservability_mjs.Gauge.DURATION_HISTOGRAM_GAUGE, {
|
|
1206
|
+
val: timeInMs
|
|
1207
|
+
});
|
|
1208
|
+
});
|
|
1209
|
+
requestLoggerMiddleware.on(stsobservability_mjs.RequestLoggerMiddlewareEventName.UpdateInstrument_D_VAL, (timeInMs) => {
|
|
1210
|
+
stsApp.UpdateInstrument(stsobservability_mjs.Gauge.DURATION_GAUGE, {
|
|
1211
|
+
val: timeInMs
|
|
1212
|
+
});
|
|
1213
|
+
});
|
|
1214
|
+
requestLoggerMiddleware.on(stsobservability_mjs.RequestLoggerMiddlewareEventName.UpdateInstrument_RC_INC, () => {
|
|
1215
|
+
stsApp.UpdateInstrument(stsobservability_mjs.Gauge.REQUEST_COUNT_GAUGE, {
|
|
1216
|
+
Inc: 1
|
|
1217
|
+
});
|
|
1218
|
+
});
|
|
1219
|
+
requestLoggerMiddleware.on(stsobservability_mjs.RequestLoggerMiddlewareEventName.UpdateInstrument_V_INC, () => {
|
|
1220
|
+
if (stsApp.InstrumentExists(stsobservability_mjs.Gauge.VELOCITY_GAUGE)) {
|
|
1221
|
+
stsApp.UpdateInstrument(stsobservability_mjs.Gauge.VELOCITY_GAUGE, {
|
|
1222
|
+
Inc: 1
|
|
1223
|
+
});
|
|
1224
|
+
}
|
|
1225
|
+
});
|
|
1226
|
+
const app = express();
|
|
1227
|
+
__privateSet(this, _app, app);
|
|
1228
|
+
const corsConfig = {
|
|
1229
|
+
credentials: true,
|
|
1230
|
+
origin: true
|
|
1231
|
+
};
|
|
1232
|
+
app.use(cors(corsConfig));
|
|
1233
|
+
app.use(cookieParser());
|
|
1234
|
+
app.use(express.urlencoded({ extended: false, limit: stsconfig_mjs.goptions.maxPayloadSize }));
|
|
1235
|
+
app.use(express.json({ limit: stsconfig_mjs.goptions.maxPayloadSize }));
|
|
1236
|
+
if (options.expressServerRouteStaticFactory) {
|
|
1237
|
+
options.expressServerRouteStaticFactory(app, stsApp);
|
|
1238
|
+
}
|
|
1239
|
+
app.use(requestLoggerMiddleware.Middleware.bind(requestLoggerMiddleware));
|
|
1240
|
+
app.use(serverNetworkMiddleware.Middleware.bind(serverNetworkMiddleware));
|
|
1241
|
+
if (options.expressServerRouteFactory) {
|
|
1242
|
+
options.expressServerRouteFactory(app, stsApp);
|
|
1243
|
+
}
|
|
1244
|
+
app.use(function(err, req, res, next) {
|
|
1245
|
+
if (err) {
|
|
1246
|
+
res.status(err.status).send(err);
|
|
1247
|
+
} else {
|
|
1248
|
+
next();
|
|
1249
|
+
}
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
get App() {
|
|
1253
|
+
return __privateGet(this, _app);
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
_app = new WeakMap();
|
|
1257
|
+
class ServerProcessBase extends ProcessBase {
|
|
1258
|
+
constructor(options) {
|
|
1259
|
+
super(options);
|
|
1260
|
+
__privateAdd(this, _masterProcessExitTime2, stsconfig_mjs.goptions.masterProcessExitTime);
|
|
1261
|
+
__privateAdd(this, _io, null);
|
|
1262
|
+
__privateAdd(this, _redisClient, null);
|
|
1263
|
+
__privateAdd(this, _httpServer2, null);
|
|
1264
|
+
__privateAdd(this, _expressServer, null);
|
|
1265
|
+
__privateAdd(this, _sockets, []);
|
|
1266
|
+
__privateAdd(this, _shuttingDown2, false);
|
|
1267
|
+
// Setup server to Prometheus scrapes:
|
|
1268
|
+
__privateAdd(this, _SetupPrometheusEndPoints, (expressServer) => {
|
|
1269
|
+
new index_js$2.AggregatorRegistry();
|
|
1270
|
+
const prefix = "sts_";
|
|
1271
|
+
index_js$2.collectDefaultMetrics({
|
|
1272
|
+
labels: { NODE_APP_INSTANCE: process.pid },
|
|
1273
|
+
prefix
|
|
1274
|
+
});
|
|
1275
|
+
const c = new index_js$2.Counter({
|
|
1276
|
+
name: "sts_test_counter",
|
|
1277
|
+
help: "Example of a counter",
|
|
1278
|
+
labelNames: ["code"]
|
|
1279
|
+
});
|
|
1280
|
+
setInterval(() => {
|
|
1281
|
+
c.inc({ code: 200 });
|
|
1282
|
+
}, 1e3).unref();
|
|
1283
|
+
setInterval(() => {
|
|
1284
|
+
c.inc({ code: 400 });
|
|
1285
|
+
c.inc({ code: "worker_" + process.pid });
|
|
1286
|
+
}, 500).unref();
|
|
1287
|
+
expressServer.get("/metrics", async (req, res) => {
|
|
1288
|
+
try {
|
|
1289
|
+
res.set("Content-Type", index_js$2.register.contentType);
|
|
1290
|
+
res.end(await index_js$2.register.metrics());
|
|
1291
|
+
} catch (ex) {
|
|
1292
|
+
res.status(500).end(ex);
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
1295
|
+
expressServer.get("/metrics/counter", async (req, res) => {
|
|
1296
|
+
try {
|
|
1297
|
+
res.set("Content-Type", index_js$2.register.contentType);
|
|
1298
|
+
res.end(await index_js$2.register.getSingleMetricAsString("test_counter"));
|
|
1299
|
+
} catch (ex) {
|
|
1300
|
+
res.status(500).end(ex);
|
|
1301
|
+
}
|
|
1302
|
+
});
|
|
1303
|
+
});
|
|
1304
|
+
__privateAdd(this, _SetupTLSServer, async (socket) => {
|
|
1305
|
+
this.LogInfoMessage("CONNECTED: " + socket.remoteAddress + ":" + socket.remotePort + " " + process.pid);
|
|
1306
|
+
__privateGet(this, _sockets).push(socket);
|
|
1307
|
+
socket.on("close", (data) => {
|
|
1308
|
+
const index = __privateGet(this, _sockets).findIndex(function(o) {
|
|
1309
|
+
return o.remoteAddress === socket.remoteAddress && o.remotePort === socket.remotePort;
|
|
1310
|
+
});
|
|
1311
|
+
if (index !== -1) __privateGet(this, _sockets).splice(index, 1);
|
|
1312
|
+
this.LogInfoMessage("CLOSED: " + socket.remoteAddress + " " + socket.remotePort + " " + process.pid);
|
|
1313
|
+
});
|
|
1314
|
+
socket.on("data", (data) => {
|
|
1315
|
+
this.LogInfoMessage("DATA " + socket.remoteAddress + ": " + socket.remotePort + ": " + data);
|
|
1316
|
+
socket.write(socket.remoteAddress + ":" + socket.remotePort + " said " + data + "\n");
|
|
1317
|
+
});
|
|
1318
|
+
});
|
|
1319
|
+
__privateAdd(this, _SetupRPCServer, async (socket) => {
|
|
1320
|
+
this.LogInfoMessage("CONNECTED: " + socket.remoteAddress + ":" + socket.remotePort + " " + process.pid);
|
|
1321
|
+
socket.on("close", (data) => {
|
|
1322
|
+
this.LogInfoMessage("CLOSED: " + socket.remoteAddress + " " + socket.remotePort + " " + process.pid);
|
|
1323
|
+
});
|
|
1324
|
+
socket.on("data", (data) => {
|
|
1325
|
+
this.LogInfoMessage("DATA " + socket.remoteAddress + ": " + data);
|
|
1326
|
+
});
|
|
1327
|
+
});
|
|
1328
|
+
__privateAdd(this, _SetupWSSServer, async () => {
|
|
1329
|
+
const options = {
|
|
1330
|
+
transports: ["websocket"]
|
|
1331
|
+
// or [ "websocket", "polling" ] (to use long-poolling. Note that the order matters)
|
|
1332
|
+
// The default path is /socket.io
|
|
1333
|
+
// This can be changed with the path option as shown below
|
|
1334
|
+
//,path: '/zzz'
|
|
1335
|
+
};
|
|
1336
|
+
__privateSet(this, _io, new wrapper_mjs.Server(__privateGet(this, _httpServer2), options));
|
|
1337
|
+
if (this.options.useSocketIoRedisAdaptor) {
|
|
1338
|
+
this.LogInfoMessage(`Using Redis for socket.io cluster management (worker)`);
|
|
1339
|
+
if (this.options.socketIoRedisAdaptorUrl) {
|
|
1340
|
+
this.LogInfoMessage(`Redis url: [${this.options.socketIoRedisAdaptorUrl}]`);
|
|
1341
|
+
__privateSet(this, _redisClient, index_js$5.createClient({ url: this.options.socketIoRedisAdaptorUrl }));
|
|
1342
|
+
} else {
|
|
1343
|
+
this.LogInfoMessage(`Redis url: [localhost]`);
|
|
1344
|
+
__privateSet(this, _redisClient, index_js$5.createClient());
|
|
1345
|
+
}
|
|
1346
|
+
await __privateGet(this, _redisClient).connect();
|
|
1347
|
+
__privateGet(this, _io).adapter(index_js$6.createAdapter(__privateGet(this, _redisClient)));
|
|
1348
|
+
this.LogInfoMessage(`Redis successfully connected.`);
|
|
1349
|
+
} else {
|
|
1350
|
+
if (this.options.clusterMode) {
|
|
1351
|
+
__privateGet(this, _io).adapter(index_js$3.createAdapter());
|
|
1352
|
+
this.LogInfoMessage(`Using nodejs cluster mode for socket.io cluster management`);
|
|
1353
|
+
} else {
|
|
1354
|
+
this.LogInfoMessage(`Not using any adaptors for socket.io cluster management.}`);
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
__privateGet(this, _io).engine.on("connection_error", (err) => {
|
|
1358
|
+
this.LogInfoMessage(err.req);
|
|
1359
|
+
this.LogInfoMessage(err.code);
|
|
1360
|
+
this.LogInfoMessage(err.message);
|
|
1361
|
+
this.LogInfoMessage(err.context);
|
|
1362
|
+
});
|
|
1363
|
+
});
|
|
1364
|
+
__privateAdd(this, _GetTLSOptions, () => {
|
|
1365
|
+
return {
|
|
1366
|
+
key: fs.readFileSync(this.options.httpsServerKeyPath),
|
|
1367
|
+
cert: fs.readFileSync(this.options.httpsServerCertificatePath)
|
|
1368
|
+
};
|
|
1369
|
+
});
|
|
1370
|
+
__privateAdd(this, _SetupExpressServer, async (useTls) => {
|
|
1371
|
+
if (useTls) {
|
|
1372
|
+
__privateSet(this, _httpServer2, node_https.createServer(__privateGet(this, _GetTLSOptions).call(this), __privateGet(this, _expressServer).App));
|
|
1373
|
+
} else {
|
|
1374
|
+
__privateSet(this, _httpServer2, node_http.createServer(__privateGet(this, _expressServer).App));
|
|
1375
|
+
}
|
|
1376
|
+
if (this.options.prometheusSupport === true) {
|
|
1377
|
+
__privateGet(this, _SetupPrometheusEndPoints).call(this, __privateGet(this, _expressServer).App);
|
|
1378
|
+
}
|
|
1379
|
+
if (this.options.wssServer === true) {
|
|
1380
|
+
await __privateGet(this, _SetupWSSServer).call(this);
|
|
1381
|
+
}
|
|
1382
|
+
__privateGet(this, _httpServer2).listen(this.options.listenPort, () => {
|
|
1383
|
+
}).on("listening", () => {
|
|
1384
|
+
this.LogInfoMessage(`live on ${this.options.endpoint}:${this.options.listenPort}${this.options.apiRoot}`);
|
|
1385
|
+
});
|
|
1386
|
+
});
|
|
1387
|
+
__privateAdd(this, _SetupTCPRawServer, async () => {
|
|
1388
|
+
__privateSet(this, _httpServer2, tls.createServer(__privateGet(this, _GetTLSOptions).call(this), __privateGet(this, _SetupTLSServer)));
|
|
1389
|
+
__privateGet(this, _httpServer2).listen(this.options.listenPort, "stscore.stsmda.org", () => {
|
|
1390
|
+
this.LogInfoMessage("TCP Server is running on port " + this.options.listenPort + ".");
|
|
1391
|
+
}).on("listening", () => {
|
|
1392
|
+
this.LogInfoMessage(`TCP live on ${this.options.endpoint}:${this.options.listenPort}${this.options.apiRoot}`);
|
|
1393
|
+
});
|
|
1394
|
+
});
|
|
1395
|
+
__privateAdd(this, _SetupJSONRPCServer, async () => {
|
|
1396
|
+
const jaysonServer = new jayson.server();
|
|
1397
|
+
jaysonServer.method("add", function(args, callback) {
|
|
1398
|
+
callback(null, args[0] + args[1]);
|
|
1399
|
+
});
|
|
1400
|
+
__privateSet(this, _httpServer2, jaysonServer.tls(__privateGet(this, _GetTLSOptions).call(this)));
|
|
1401
|
+
__privateGet(this, _httpServer2).on("secureConnection", __privateGet(this, _SetupRPCServer));
|
|
1402
|
+
__privateGet(this, _httpServer2).listen(this.options.listenPort, "stscore.stsmda.org", () => {
|
|
1403
|
+
this.LogInfoMessage("JSON RPC 2.0 Server is running on port " + this.options.listenPort + ".");
|
|
1404
|
+
}).on("listening", () => {
|
|
1405
|
+
this.LogInfoMessage(`JSON RPC 2.0 live on ${this.options.endpoint}:${this.options.listenPort}${this.options.apiRoot}`);
|
|
1406
|
+
});
|
|
1407
|
+
});
|
|
1408
|
+
__publicField(this, "TerminateSocketIO", async () => {
|
|
1409
|
+
var _a;
|
|
1410
|
+
if (this.options.wssServer === true && __privateGet(this, _io) !== null) {
|
|
1411
|
+
const logPrefix = `ServerProcessBase:TerminateSockets():${process.pid}:`;
|
|
1412
|
+
this.LogInfoMessage(`${logPrefix} Disconnect SocketIO Sockets.`);
|
|
1413
|
+
await stsutils.Sleep(250);
|
|
1414
|
+
await ((_a = __privateGet(this, _io)) == null ? void 0 : _a.of("/").adapter.close());
|
|
1415
|
+
if (this.socketIoServerHelper !== null) {
|
|
1416
|
+
await this.socketIoServerHelper.CloseAdaptors();
|
|
1417
|
+
await stsutils.Sleep(50);
|
|
1418
|
+
if (__privateGet(this, _redisClient)) {
|
|
1419
|
+
__privateGet(this, _redisClient).disconnect();
|
|
1420
|
+
await stsutils.Sleep(50);
|
|
1421
|
+
}
|
|
1422
|
+
this.LogInfoMessage(`${logPrefix} this.socketIoServerHelper.DisconnectSockets()`);
|
|
1423
|
+
await this.socketIoServerHelper.DisconnectSockets();
|
|
1424
|
+
} else {
|
|
1425
|
+
this.LogInfoMessage(`${logPrefix} this.#io.disconnectSockets()`);
|
|
1426
|
+
if (__privateGet(this, _redisClient)) {
|
|
1427
|
+
__privateGet(this, _redisClient).disconnect();
|
|
1428
|
+
await stsutils.Sleep(50);
|
|
1429
|
+
}
|
|
1430
|
+
__privateGet(this, _io).disconnectSockets();
|
|
1431
|
+
}
|
|
1432
|
+
this.socketIoServerHelper = null;
|
|
1433
|
+
__privateSet(this, _io, null);
|
|
1434
|
+
}
|
|
1435
|
+
});
|
|
1436
|
+
__publicField(this, "TerminateHTTPServer", async () => {
|
|
1437
|
+
const logPrefix = `ServerProcessBase:TerminateHTTPServer():${process.pid}:`;
|
|
1438
|
+
if (__privateGet(this, _httpServer2) !== null) {
|
|
1439
|
+
if (stsconfig_mjs.goptions.STSServerType.localeCompare("TCPRAW_TLS") === 0) {
|
|
1440
|
+
__privateGet(this, _sockets).forEach((socket, index, array) => {
|
|
1441
|
+
this.LogInfoMessage(chalk.yellow(`${logPrefix} TCP Socket destroy, remote address: [${socket.remoteAddress}], remote port: [${socket.remotePort}]`));
|
|
1442
|
+
socket.destroy();
|
|
1443
|
+
});
|
|
1444
|
+
}
|
|
1445
|
+
this.LogInfoMessage(`${logPrefix} Closing httpServer.`);
|
|
1446
|
+
await __privateGet(this, _httpServer2).close();
|
|
1447
|
+
__privateSet(this, _httpServer2, null);
|
|
1448
|
+
}
|
|
1449
|
+
});
|
|
1450
|
+
// Terminate in order;
|
|
1451
|
+
// forked worker threads (send signal)
|
|
1452
|
+
// De-Register service
|
|
1453
|
+
// systeminformation observers
|
|
1454
|
+
// instrument timers (gauge etc.)
|
|
1455
|
+
// publisher
|
|
1456
|
+
// terminate UI (if loaded)
|
|
1457
|
+
__publicField(this, "Terminate", async (clusterPerformExit, signal) => {
|
|
1458
|
+
const logPrefix = `ServerProcessBase:Terminate():${process.pid}:`;
|
|
1459
|
+
if (__privateGet(this, _shuttingDown2) === false) {
|
|
1460
|
+
__privateSet(this, _shuttingDown2, true);
|
|
1461
|
+
if (signal) {
|
|
1462
|
+
this.LogInfoMessage(this.GetSignalColour(signal)(`${logPrefix} Received signal: ${signal}`));
|
|
1463
|
+
} else {
|
|
1464
|
+
this.LogInfoMessage(this.GetSignalColour(null)(`${logPrefix} Received Terminate without signal.`));
|
|
1465
|
+
}
|
|
1466
|
+
await this.ProcessTerminate();
|
|
1467
|
+
this.TerminateUIController();
|
|
1468
|
+
await this.TerminateSocketIO();
|
|
1469
|
+
await this.TerminateHTTPServer();
|
|
1470
|
+
await this.TerminateDatabase();
|
|
1471
|
+
if (this.options.clusterMode) {
|
|
1472
|
+
this.LogInfoMessage(`${logPrefix} clusterPerformExit value: [${clusterPerformExit}]`);
|
|
1473
|
+
if (clusterPerformExit) {
|
|
1474
|
+
this.LogInfoMessage(`${logPrefix} Process will self terminate with process.exit(0).`);
|
|
1475
|
+
} else {
|
|
1476
|
+
this.LogInfoMessage(`${logPrefix} Child process will not self terminate. Terminate will be handled by master process.`);
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
this.TerminateInstrumentController();
|
|
1480
|
+
await stsutils.Sleep(1e3);
|
|
1481
|
+
if (this.options.clusterMode === true) {
|
|
1482
|
+
if (clusterPerformExit === true) {
|
|
1483
|
+
setTimeout(() => {
|
|
1484
|
+
process.exit(0);
|
|
1485
|
+
}, 0);
|
|
1486
|
+
}
|
|
1487
|
+
} else {
|
|
1488
|
+
this.ProcessExit(__privateGet(this, _masterProcessExitTime2));
|
|
1489
|
+
}
|
|
1490
|
+
} else {
|
|
1491
|
+
this.LogInfoMessage(`${logPrefix} Process already terminating.`);
|
|
1492
|
+
}
|
|
1493
|
+
});
|
|
1494
|
+
__publicField(this, "SetupSTSServer", async () => {
|
|
1495
|
+
switch (stsconfig_mjs.goptions.STSServerType) {
|
|
1496
|
+
case "EXPRESS":
|
|
1497
|
+
await __privateGet(this, _SetupExpressServer).call(this, false);
|
|
1498
|
+
break;
|
|
1499
|
+
case "EXPRESS_TLS":
|
|
1500
|
+
await __privateGet(this, _SetupExpressServer).call(this, true);
|
|
1501
|
+
break;
|
|
1502
|
+
case "TCPRAW_TLS":
|
|
1503
|
+
await __privateGet(this, _SetupTCPRawServer).call(this);
|
|
1504
|
+
break;
|
|
1505
|
+
case "JSONRPC2_TLS":
|
|
1506
|
+
await __privateGet(this, _SetupJSONRPCServer).call(this);
|
|
1507
|
+
break;
|
|
1508
|
+
}
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1511
|
+
get httpServer() {
|
|
1512
|
+
return __privateGet(this, _httpServer2);
|
|
1513
|
+
}
|
|
1514
|
+
get io() {
|
|
1515
|
+
return __privateGet(this, _io);
|
|
1516
|
+
}
|
|
1517
|
+
get expressServer() {
|
|
1518
|
+
return __privateGet(this, _expressServer);
|
|
1519
|
+
}
|
|
1520
|
+
set expressServer(val) {
|
|
1521
|
+
__privateSet(this, _expressServer, val);
|
|
1522
|
+
}
|
|
1523
|
+
get shuttingDown() {
|
|
1524
|
+
return __privateGet(this, _shuttingDown2);
|
|
1525
|
+
}
|
|
1526
|
+
async SetupServer() {
|
|
1527
|
+
return new Promise((resolve, reject) => {
|
|
1528
|
+
try {
|
|
1529
|
+
this.SetupInstrumentation();
|
|
1530
|
+
setTimeout(async () => {
|
|
1531
|
+
try {
|
|
1532
|
+
await this.SetupServerEx();
|
|
1533
|
+
resolve(true);
|
|
1534
|
+
} catch (error) {
|
|
1535
|
+
reject(error);
|
|
1536
|
+
}
|
|
1537
|
+
}, 100);
|
|
1538
|
+
} catch (error) {
|
|
1539
|
+
reject(error);
|
|
1540
|
+
}
|
|
1541
|
+
});
|
|
1542
|
+
}
|
|
1543
|
+
ProcessStarted() {
|
|
1544
|
+
const transport = new STSTransportLoggerWinston({
|
|
1545
|
+
stsApp: this
|
|
1546
|
+
});
|
|
1547
|
+
setTimeout(() => {
|
|
1548
|
+
this.options.logger.add(transport);
|
|
1549
|
+
}, 0);
|
|
1550
|
+
}
|
|
1551
|
+
async SetupServerEx() {
|
|
1552
|
+
this.LogInfoMessage(chalk.green(`ServerProcessBase:SetupServerEx(): Main Process:${process.pid} Starting ...`));
|
|
1553
|
+
this.ProcessStartup();
|
|
1554
|
+
if (this.options.expressServerRouteFactory || this.options.expressServerRouteStaticFactory) {
|
|
1555
|
+
this.expressServer = new STSExpressServer(this.options, this);
|
|
1556
|
+
}
|
|
1557
|
+
this.LogInfoMessage(`ServerProcessBase:SetupServerEx(): Worker instance starting. Service instance Id: [${this.options.serviceInstanceId}]`);
|
|
1558
|
+
process.on("SIGTERM", async () => {
|
|
1559
|
+
this.LogInfoMessage(`ServerProcessBase:SetupServerEx(): SIGTERM signal received for worker: ${process.pid}`);
|
|
1560
|
+
await this.Terminate(true, true);
|
|
1561
|
+
});
|
|
1562
|
+
process.on("SIGINT", async () => {
|
|
1563
|
+
this.LogInfoMessage(`ServerProcessBase:SetupServerEx(): SIGINT signal received for worker: ${process.pid}`);
|
|
1564
|
+
await this.Terminate(true, true);
|
|
1565
|
+
});
|
|
1566
|
+
process.on("exit", (code) => {
|
|
1567
|
+
if (code === 0) {
|
|
1568
|
+
this.LogInfoMessage(chalk.green(`ServerProcessBase:SetupServerEx(): Process: ${process.pid} terminated gracefully with code: ${code}`));
|
|
1569
|
+
} else {
|
|
1570
|
+
this.LogInfoMessage(chalk.red(`ServerProcessBase:SetupServerEx(): Process: ${process.pid} terminated with code: ${code}`));
|
|
1571
|
+
}
|
|
1572
|
+
});
|
|
1573
|
+
await this.SetupSTSServer();
|
|
1574
|
+
this.ProcessStarted();
|
|
1575
|
+
this.LogInfoMessage(chalk.green(`ServerProcessBase:SetupServerEx(): Main Process:${process.pid} Started`));
|
|
1576
|
+
return true;
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
_masterProcessExitTime2 = new WeakMap();
|
|
1580
|
+
_io = new WeakMap();
|
|
1581
|
+
_redisClient = new WeakMap();
|
|
1582
|
+
_httpServer2 = new WeakMap();
|
|
1583
|
+
_expressServer = new WeakMap();
|
|
1584
|
+
_sockets = new WeakMap();
|
|
1585
|
+
_shuttingDown2 = new WeakMap();
|
|
1586
|
+
_SetupPrometheusEndPoints = new WeakMap();
|
|
1587
|
+
_SetupTLSServer = new WeakMap();
|
|
1588
|
+
_SetupRPCServer = new WeakMap();
|
|
1589
|
+
_SetupWSSServer = new WeakMap();
|
|
1590
|
+
_GetTLSOptions = new WeakMap();
|
|
1591
|
+
_SetupExpressServer = new WeakMap();
|
|
1592
|
+
_SetupTCPRawServer = new WeakMap();
|
|
1593
|
+
_SetupJSONRPCServer = new WeakMap();
|
|
1594
|
+
class SingleProcessBase extends ServerProcessBase {
|
|
1595
|
+
/**
|
|
1596
|
+
*
|
|
1597
|
+
* @param {SingleProcessBaseOptions} options
|
|
1598
|
+
*/
|
|
1599
|
+
constructor(options) {
|
|
1600
|
+
super(options);
|
|
1601
|
+
__publicField(this, "SetupServerEx", async () => {
|
|
1602
|
+
await super.SetupServerEx();
|
|
1603
|
+
this.LogSystemTelemetry();
|
|
1604
|
+
return true;
|
|
1605
|
+
});
|
|
1606
|
+
}
|
|
1607
|
+
CollectAdditionalTelemetry() {
|
|
1608
|
+
const siValueObject = {
|
|
1609
|
+
currentLoad: "currentLoad"
|
|
1610
|
+
};
|
|
1611
|
+
si.get(siValueObject).then((data) => {
|
|
1612
|
+
this.UpdateInstrument(stsobservability_mjs.Gauge.CPU_SYSTEM_LOAD_GAUGE, {
|
|
1613
|
+
val: data.currentLoad.currentLoad
|
|
1614
|
+
});
|
|
1615
|
+
});
|
|
1616
|
+
}
|
|
1617
|
+
GetAdditionalInstruments() {
|
|
1618
|
+
return [
|
|
1619
|
+
[stsobservability_mjs.Gauge.CPU_SYSTEM_LOAD_GAUGE, stsobservability_mjs.GaugeTypes.INSTRUMENT_GAUGE, {
|
|
1620
|
+
interval: stsconfig_mjs.goptions.instrumentationObservationInterval,
|
|
1621
|
+
sampleSize: stsconfig_mjs.goptions.instrumentationTimeWindow
|
|
1622
|
+
}]
|
|
1623
|
+
];
|
|
1624
|
+
}
|
|
1625
|
+
/**
|
|
1626
|
+
* UIController (instance of UIController) to manage a console based user interface associated for this node application.
|
|
1627
|
+
* @returns UIController instance to manage a console based user interface associated for this node application. Null for no capability.
|
|
1628
|
+
*/
|
|
1629
|
+
GetUIController() {
|
|
1630
|
+
return null;
|
|
1631
|
+
}
|
|
1632
|
+
async TerminateApplication() {
|
|
1633
|
+
await this.Terminate(false, "SIGINT");
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
class WorkerProcessBase extends ServerProcessBase {
|
|
1637
|
+
constructor(options) {
|
|
1638
|
+
super(options);
|
|
1639
|
+
__privateAdd(this, _inFlightMessage, {});
|
|
1640
|
+
__privateAdd(this, _requestResponseMessageTimeout, 5e3);
|
|
1641
|
+
//@@ config
|
|
1642
|
+
__privateAdd(this, _pingTimeout, null);
|
|
1643
|
+
__privateAdd(this, _SendMessageToParentProcess, (message) => {
|
|
1644
|
+
return new Promise((resolve, reject) => {
|
|
1645
|
+
if (__privateGet(this, _inFlightMessage)[message.id]) {
|
|
1646
|
+
reject(`Message with id: [${message.id}] already exists within the Request/Response record structure`);
|
|
1647
|
+
} else {
|
|
1648
|
+
__privateGet(this, _inFlightMessage)[message.id] = {
|
|
1649
|
+
iPCMessagePayload: { ...message },
|
|
1650
|
+
cb: () => {
|
|
1651
|
+
const detail = __privateGet(this, _inFlightMessage)[message.id].iPCMessagePayload.responseDetail;
|
|
1652
|
+
clearTimeout(__privateGet(this, _inFlightMessage)[message.id].timeout);
|
|
1653
|
+
setTimeout(() => {
|
|
1654
|
+
delete __privateGet(this, _inFlightMessage)[message.id];
|
|
1655
|
+
}, 0).unref();
|
|
1656
|
+
resolve(detail);
|
|
1657
|
+
},
|
|
1658
|
+
timeout: setTimeout(() => {
|
|
1659
|
+
setTimeout(() => {
|
|
1660
|
+
delete __privateGet(this, _inFlightMessage)[message.id];
|
|
1661
|
+
}, 0).unref();
|
|
1662
|
+
reject("Did not receive response form parent process.");
|
|
1663
|
+
}, __privateGet(this, _requestResponseMessageTimeout))
|
|
1664
|
+
// max message timeout allowed
|
|
1665
|
+
};
|
|
1666
|
+
process.send(message);
|
|
1667
|
+
}
|
|
1668
|
+
});
|
|
1669
|
+
});
|
|
1670
|
+
__publicField(this, "AddWorker", async (options) => {
|
|
1671
|
+
const workerResponse = await __privateGet(this, _SendMessageToParentProcess).call(this, {
|
|
1672
|
+
requestResponse: true,
|
|
1673
|
+
id: index_js$4.v4(),
|
|
1674
|
+
command: IPCMessageCommand.AddWorker,
|
|
1675
|
+
requestDetail: {
|
|
1676
|
+
options
|
|
1677
|
+
}
|
|
1678
|
+
});
|
|
1679
|
+
return workerResponse.workerId;
|
|
1680
|
+
});
|
|
1681
|
+
__publicField(this, "DeleteWorker", async (workerId, options) => {
|
|
1682
|
+
const workerResponse = await __privateGet(this, _SendMessageToParentProcess).call(this, {
|
|
1683
|
+
requestResponse: true,
|
|
1684
|
+
id: index_js$4.v4(),
|
|
1685
|
+
command: IPCMessageCommand.DeleteWorker,
|
|
1686
|
+
requestDetail: {
|
|
1687
|
+
options,
|
|
1688
|
+
workerId
|
|
1689
|
+
}
|
|
1690
|
+
});
|
|
1691
|
+
return workerResponse;
|
|
1692
|
+
});
|
|
1693
|
+
__publicField(this, "GetMasterProcessOptions", async () => {
|
|
1694
|
+
const parentResponse = await __privateGet(this, _SendMessageToParentProcess).call(this, {
|
|
1695
|
+
requestResponse: true,
|
|
1696
|
+
id: index_js$4.v4(),
|
|
1697
|
+
command: IPCMessageCommand.GetConfig,
|
|
1698
|
+
requestDetail: {}
|
|
1699
|
+
});
|
|
1700
|
+
return parentResponse;
|
|
1701
|
+
});
|
|
1702
|
+
__publicField(this, "GetNumCPUs", async () => {
|
|
1703
|
+
const valueObject = {
|
|
1704
|
+
cpu: "*"
|
|
1705
|
+
};
|
|
1706
|
+
const sysinfo = await si.get(valueObject);
|
|
1707
|
+
let numCPUs = 2;
|
|
1708
|
+
if (stsconfig_mjs.goptions.useCPUs > 0) {
|
|
1709
|
+
if (stsconfig_mjs.goptions.useCPUs >= 1) {
|
|
1710
|
+
numCPUs = stsconfig_mjs.goptions.useCPUs;
|
|
1711
|
+
} else {
|
|
1712
|
+
numCPUs = Math.round(sysinfo.cpu.cores * stsconfig_mjs.goptions.useCPUs);
|
|
1713
|
+
}
|
|
1714
|
+
} else {
|
|
1715
|
+
numCPUs = sysinfo.cpu.physicalCores;
|
|
1716
|
+
}
|
|
1717
|
+
return numCPUs;
|
|
1718
|
+
});
|
|
1719
|
+
__publicField(this, "GetSystemTelemetry", async () => {
|
|
1720
|
+
const valueObject = {
|
|
1721
|
+
system: "*",
|
|
1722
|
+
osInfo: "*",
|
|
1723
|
+
cpu: "*",
|
|
1724
|
+
mem: "*",
|
|
1725
|
+
dockerInfo: "*",
|
|
1726
|
+
//dockerImages: '*',
|
|
1727
|
+
dockerContainers: "*"
|
|
1728
|
+
};
|
|
1729
|
+
const sysinfo = await si.get(valueObject);
|
|
1730
|
+
const numCPUs = await this.GetNumCPUs();
|
|
1731
|
+
const hostname = sysinfo.osInfo.hostname;
|
|
1732
|
+
const hostaddr = GetFirstNetworkInterface();
|
|
1733
|
+
const promArray = [];
|
|
1734
|
+
sysinfo.dockerContainers.forEach((dc) => {
|
|
1735
|
+
const dcs = promArray.push(si.dockerContainerStats(dc.id));
|
|
1736
|
+
console.log(dcs);
|
|
1737
|
+
});
|
|
1738
|
+
const dockerContainerStats = await Promise.all(promArray);
|
|
1739
|
+
const sysInfo = {
|
|
1740
|
+
serviceInstanceId: this.options.serviceInstanceId,
|
|
1741
|
+
serviceProcessContext: this.options.serviceProcessContext,
|
|
1742
|
+
hostname,
|
|
1743
|
+
numCPUs,
|
|
1744
|
+
hostaddr,
|
|
1745
|
+
system: sysinfo.system,
|
|
1746
|
+
osInfo: sysinfo.osInfo,
|
|
1747
|
+
cpu: sysinfo.cpu,
|
|
1748
|
+
mem: sysinfo.mem,
|
|
1749
|
+
dockerInfo: sysinfo.dockerInfo,
|
|
1750
|
+
dockerContainers: sysinfo.dockerContainers,
|
|
1751
|
+
dockerContainerStats
|
|
1752
|
+
};
|
|
1753
|
+
return sysInfo;
|
|
1754
|
+
});
|
|
1755
|
+
__publicField(this, "SetupServerEx", async () => {
|
|
1756
|
+
await super.SetupServerEx();
|
|
1757
|
+
process.on("message", async (msg) => {
|
|
1758
|
+
if (msg.requestResponse) {
|
|
1759
|
+
const iPCMessagePayload = msg;
|
|
1760
|
+
if (iPCMessagePayload.id) {
|
|
1761
|
+
if (__privateGet(this, _inFlightMessage)[iPCMessagePayload.id]) {
|
|
1762
|
+
const responseMessage = __privateGet(this, _inFlightMessage)[iPCMessagePayload.id];
|
|
1763
|
+
responseMessage.iPCMessagePayload.responseDetail = { ...iPCMessagePayload.responseDetail };
|
|
1764
|
+
responseMessage.cb();
|
|
1765
|
+
} else {
|
|
1766
|
+
throw new Error(`Could not find Request/Response message with id: [${iPCMessagePayload.id}]`);
|
|
1767
|
+
}
|
|
1768
|
+
} else {
|
|
1769
|
+
throw new Error(`Message does not have id attribute. [${JSON.stringify(iPCMessagePayload)}]`);
|
|
1770
|
+
}
|
|
1771
|
+
return;
|
|
1772
|
+
}
|
|
1773
|
+
if (msg.command) {
|
|
1774
|
+
switch (msg.command) {
|
|
1775
|
+
case "Terminate":
|
|
1776
|
+
this.LogInfoMessage(chalk.grey(`Received ` + chalk.bold.italic(`Terminate`) + ` message from master thread`));
|
|
1777
|
+
await this.Terminate(true, false);
|
|
1778
|
+
break;
|
|
1779
|
+
case "TerminateAndKill":
|
|
1780
|
+
this.LogInfoMessage(chalk.grey(`Received ` + chalk.bold.italic(`Terminate`) + ` message from master thread`));
|
|
1781
|
+
await this.Terminate(true, true);
|
|
1782
|
+
break;
|
|
1783
|
+
case "Message":
|
|
1784
|
+
this.ReceivedMessageFromMaster(msg.data);
|
|
1785
|
+
break;
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
});
|
|
1789
|
+
return true;
|
|
1790
|
+
});
|
|
1791
|
+
}
|
|
1792
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1793
|
+
ReceivedMessageFromMaster(msg) {
|
|
1794
|
+
}
|
|
1795
|
+
CollectAdditionalTelemetry() {
|
|
1796
|
+
this.httpServer.getConnections((error, count) => {
|
|
1797
|
+
this.UpdateInstrument(stsobservability_mjs.Gauge.CONNECTION_COUNT_GAUGE, {
|
|
1798
|
+
val: count
|
|
1799
|
+
});
|
|
1800
|
+
});
|
|
1801
|
+
}
|
|
1802
|
+
ProcessTerminate() {
|
|
1803
|
+
if (__privateGet(this, _pingTimeout)) {
|
|
1804
|
+
clearTimeout(__privateGet(this, _pingTimeout));
|
|
1805
|
+
}
|
|
1806
|
+
return super.ProcessTerminate();
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
_inFlightMessage = new WeakMap();
|
|
1810
|
+
_requestResponseMessageTimeout = new WeakMap();
|
|
1811
|
+
_pingTimeout = new WeakMap();
|
|
1812
|
+
_SendMessageToParentProcess = new WeakMap();
|
|
1813
|
+
class STSControllerBase {
|
|
1814
|
+
constructor(stsApp) {
|
|
1815
|
+
__privateAdd(this, _stsApp);
|
|
1816
|
+
__privateSet(this, _stsApp, stsApp);
|
|
1817
|
+
}
|
|
1818
|
+
get stsApp() {
|
|
1819
|
+
return __privateGet(this, _stsApp);
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
_stsApp = new WeakMap();
|
|
1823
|
+
class STSLatencyController extends STSControllerBase {
|
|
1824
|
+
constructor(stsApp) {
|
|
1825
|
+
super(stsApp);
|
|
1826
|
+
}
|
|
1827
|
+
// curl http://localhost:3000/api/v1/latency/latency
|
|
1828
|
+
async stslatency(req, res) {
|
|
1829
|
+
try {
|
|
1830
|
+
const retVal = {
|
|
1831
|
+
data: `Ping Completed At: ${Date.now()}`,
|
|
1832
|
+
pid: process.pid,
|
|
1833
|
+
ppid: process.ppid
|
|
1834
|
+
};
|
|
1835
|
+
return res.status(index_js$1.StatusCodes.OK).send(retVal);
|
|
1836
|
+
} catch (error) {
|
|
1837
|
+
this.stsApp.LogErrorMessage(error);
|
|
1838
|
+
return res.status(index_js$1.StatusCodes.INTERNAL_SERVER_ERROR).send({ status: index_js$1.StatusCodes.INTERNAL_SERVER_ERROR, error: "Operation was not successful", detail: error });
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
class STSRouterBase {
|
|
1843
|
+
constructor(stsApp) {
|
|
1844
|
+
__privateAdd(this, _router);
|
|
1845
|
+
__privateAdd(this, _stsApp2);
|
|
1846
|
+
__privateSet(this, _stsApp2, stsApp);
|
|
1847
|
+
__privateSet(this, _router, express.Router());
|
|
1848
|
+
}
|
|
1849
|
+
get router() {
|
|
1850
|
+
return __privateGet(this, _router);
|
|
1851
|
+
}
|
|
1852
|
+
get stsApp() {
|
|
1853
|
+
return __privateGet(this, _stsApp2);
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
_router = new WeakMap();
|
|
1857
|
+
_stsApp2 = new WeakMap();
|
|
1858
|
+
class STSLatencyRoute extends STSRouterBase {
|
|
1859
|
+
constructor(stsApp) {
|
|
1860
|
+
super(stsApp);
|
|
1861
|
+
const latencyController = new STSLatencyController(stsApp);
|
|
1862
|
+
const { stslatency } = latencyController;
|
|
1863
|
+
this.router.get("/latency", stslatency.bind(latencyController));
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
class PublishTransportUtils {
|
|
1867
|
+
static GetServiceContext(nid) {
|
|
1868
|
+
if (nid === stsutils.ModelDelimeter.ROOT) {
|
|
1869
|
+
return { root: stsutils.ModelDelimeter.ROOT };
|
|
1870
|
+
}
|
|
1871
|
+
const context = { nid };
|
|
1872
|
+
const idsplit = nid.split(stsutils.ModelDelimeter.SEPERATOR);
|
|
1873
|
+
const serviceId = idsplit[0];
|
|
1874
|
+
const serviceInstanceId = idsplit[1].split(stsutils.ModelDelimeter.NID_SEPERATOR)[0];
|
|
1875
|
+
const serviceInstanceProcessId = idsplit[1].split(stsutils.ModelDelimeter.NID_SEPERATOR)[1];
|
|
1876
|
+
const serviceIdSplit = serviceId.split(stsutils.ModelDelimeter.COMPONENT_SEPERATOR);
|
|
1877
|
+
const serviceName = serviceIdSplit[0];
|
|
1878
|
+
const serviceVersion = serviceIdSplit[1];
|
|
1879
|
+
context.serviceId = serviceId;
|
|
1880
|
+
if (typeof serviceInstanceId != "undefined") {
|
|
1881
|
+
const serviceInstanceIdSplit = serviceInstanceId.split(stsutils.ModelDelimeter.COMPONENT_SEPERATOR);
|
|
1882
|
+
const sid = serviceInstanceIdSplit[0];
|
|
1883
|
+
const hostName = serviceInstanceIdSplit[1];
|
|
1884
|
+
context.serviceInstanceId = serviceInstanceId;
|
|
1885
|
+
context.sid = sid;
|
|
1886
|
+
context.hostName = hostName;
|
|
1887
|
+
if (typeof serviceInstanceProcessId != "undefined") {
|
|
1888
|
+
const serviceInstanceProcessIdSplit = serviceInstanceProcessId.split(stsutils.ModelDelimeter.COMPONENT_SEPERATOR);
|
|
1889
|
+
const pid = parseInt(serviceInstanceProcessIdSplit[0]);
|
|
1890
|
+
const ppid = parseInt(serviceInstanceProcessIdSplit[1]);
|
|
1891
|
+
const isMaster = pid === ppid ? true : false;
|
|
1892
|
+
context.serviceInstanceProcessId = serviceInstanceProcessId;
|
|
1893
|
+
context.pid = pid;
|
|
1894
|
+
context.ppid = ppid;
|
|
1895
|
+
context.isMaster = isMaster;
|
|
1896
|
+
context.isWorker = !isMaster;
|
|
1897
|
+
context.serviceName = serviceName;
|
|
1898
|
+
context.serviceVersion = serviceVersion;
|
|
1899
|
+
context.serviceInstanceId = serviceInstanceId;
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
return context;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
function UpdateSTSTransportWithDebugger(logger, newDebugger) {
|
|
1906
|
+
const stsTransport = logger.transports.find((transport) => {
|
|
1907
|
+
return transport instanceof STSTransportWinston;
|
|
1908
|
+
});
|
|
1909
|
+
if (stsTransport) {
|
|
1910
|
+
stsTransport.debugger = newDebugger;
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
class STSTransportWinston extends Transport {
|
|
1914
|
+
constructor(opts) {
|
|
1915
|
+
super(opts);
|
|
1916
|
+
__privateAdd(this, _options3);
|
|
1917
|
+
__privateSet(this, _options3, opts);
|
|
1918
|
+
}
|
|
1919
|
+
get debugger() {
|
|
1920
|
+
return __privateGet(this, _options3).debugger;
|
|
1921
|
+
}
|
|
1922
|
+
set debugger(newDebugger) {
|
|
1923
|
+
__privateGet(this, _options3).debugger = newDebugger;
|
|
1924
|
+
}
|
|
1925
|
+
log(info, callback) {
|
|
1926
|
+
if (info[Symbol.for("level")] == "debug") {
|
|
1927
|
+
if (__privateGet(this, _options3).debugger) {
|
|
1928
|
+
__privateGet(this, _options3).debugger(info.message);
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
this.emit("logged", info);
|
|
1932
|
+
callback();
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
_options3 = new WeakMap();
|
|
1936
|
+
exports2.CreateServiceProcessContext = CreateServiceProcessContext;
|
|
1937
|
+
exports2.IPCMessageCommand = IPCMessageCommand;
|
|
1938
|
+
exports2.MasterProcessBase = MasterProcessBase;
|
|
1939
|
+
exports2.ProcessBase = ProcessBase;
|
|
1940
|
+
exports2.PublishTransportUtils = PublishTransportUtils;
|
|
1941
|
+
exports2.STSControllerBase = STSControllerBase;
|
|
1942
|
+
exports2.STSLatencyController = STSLatencyController;
|
|
1943
|
+
exports2.STSLatencyRoute = STSLatencyRoute;
|
|
1944
|
+
exports2.STSRouterBase = STSRouterBase;
|
|
1945
|
+
exports2.STSTransportLoggerWinston = STSTransportLoggerWinston;
|
|
1946
|
+
exports2.STSTransportWinston = STSTransportWinston;
|
|
1947
|
+
exports2.ServerProcessBase = ServerProcessBase;
|
|
1948
|
+
exports2.SingleProcessBase = SingleProcessBase;
|
|
1949
|
+
exports2.UpdateSTSTransportWithDebugger = UpdateSTSTransportWithDebugger;
|
|
1950
|
+
exports2.WorkerProcessBase = WorkerProcessBase;
|
|
1951
|
+
exports2.iss = iss;
|
|
1952
|
+
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
|
|
1953
|
+
});
|
|
1954
|
+
//# sourceMappingURL=stsappframework.umd.js.map
|