@nsshunt/stsappframework 3.3.133 → 3.3.135
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/README.md +42 -0
- package/dist/commonTypes.js +6 -6
- package/dist/commonTypes.js.map +1 -1
- package/dist/controller/stscontrollerbase.js.map +1 -1
- package/dist/controller/stslatencycontroller.js +10 -4
- package/dist/controller/stslatencycontroller.js.map +1 -1
- package/dist/grpc/grpcServer.js +32 -31
- package/dist/grpc/grpcServer.js.map +1 -1
- package/dist/index.js +15 -15
- package/dist/index.js.map +1 -1
- package/dist/logger/socketClientLogPublisher.js +12 -12
- package/dist/logger/socketClientLogPublisher.js.map +1 -1
- package/dist/logger/stsTransportLoggerSocket.js +9 -9
- package/dist/logger/stsTransportLoggerSocket.js.map +1 -1
- package/dist/logger/stsTransportLoggerWinston.js +2 -2
- package/dist/logger/stsTransportLoggerWinston.js.map +1 -1
- package/dist/logger/stsTransportWinston.js +3 -3
- package/dist/logger/stsTransportWinston.js.map +1 -1
- package/dist/middleware/serverNetworkMiddleware.js +41 -34
- package/dist/middleware/serverNetworkMiddleware.js.map +1 -1
- package/dist/network.js +2 -2
- package/dist/network.js.map +1 -1
- package/dist/process/masterprocessbase.js +92 -79
- package/dist/process/masterprocessbase.js.map +1 -1
- package/dist/process/processbase.js +162 -139
- package/dist/process/processbase.js.map +1 -1
- package/dist/process/serverprocessbase.js +104 -63
- package/dist/process/serverprocessbase.js.map +1 -1
- package/dist/process/singleprocessbase.js +17 -14
- package/dist/process/singleprocessbase.js.map +1 -1
- package/dist/process/workerprocessbase.js +39 -34
- package/dist/process/workerprocessbase.js.map +1 -1
- package/dist/publishertransports/publishTransportUtils.js +4 -4
- package/dist/publishertransports/publishTransportUtils.js.map +1 -1
- package/dist/route/stslatencyroute.js +3 -3
- package/dist/route/stslatencyroute.js.map +1 -1
- package/dist/route/stsrouterbase.js +1 -1
- package/dist/route/stsrouterbase.js.map +1 -1
- package/dist/server.test.js +2 -2
- package/dist/stsexpressserver.js +22 -19
- package/dist/stsexpressserver.js.map +1 -1
- package/dist/validation/errors.js +2 -2
- package/package.json +17 -16
- package/types/commonTypes.d.ts +27 -23
- package/types/commonTypes.d.ts.map +1 -1
- package/types/controller/stscontrollerbase.d.ts +1 -1
- package/types/controller/stscontrollerbase.d.ts.map +1 -1
- package/types/controller/stslatencycontroller.d.ts +2 -2
- package/types/controller/stslatencycontroller.d.ts.map +1 -1
- package/types/grpc/grpcServer.d.ts.map +1 -1
- package/types/index.d.ts +15 -15
- package/types/index.d.ts.map +1 -1
- package/types/logger/socketClientLogPublisher.d.ts +3 -3
- package/types/logger/socketClientLogPublisher.d.ts.map +1 -1
- package/types/logger/stsTransportLoggerSocket.d.ts +2 -2
- package/types/logger/stsTransportLoggerSocket.d.ts.map +1 -1
- package/types/logger/stsTransportLoggerWinston.d.ts +2 -2
- package/types/logger/stsTransportLoggerWinston.d.ts.map +1 -1
- package/types/logger/stsTransportWinston.d.ts +2 -2
- package/types/logger/stsTransportWinston.d.ts.map +1 -1
- package/types/middleware/serverNetworkMiddleware.d.ts +3 -3
- package/types/middleware/serverNetworkMiddleware.d.ts.map +1 -1
- package/types/network.d.ts.map +1 -1
- package/types/process/masterprocessbase.d.ts +4 -4
- package/types/process/masterprocessbase.d.ts.map +1 -1
- package/types/process/processbase.d.ts +16 -7
- package/types/process/processbase.d.ts.map +1 -1
- package/types/process/serverprocessbase.d.ts +3 -3
- package/types/process/serverprocessbase.d.ts.map +1 -1
- package/types/process/singleprocessbase.d.ts +3 -3
- package/types/process/singleprocessbase.d.ts.map +1 -1
- package/types/process/workerprocessbase.d.ts +3 -3
- package/types/process/workerprocessbase.d.ts.map +1 -1
- package/types/publishertransports/publishTransportUtils.d.ts +1 -1
- package/types/publishertransports/publishTransportUtils.d.ts.map +1 -1
- package/types/route/stslatencyroute.d.ts +2 -2
- package/types/route/stslatencyroute.d.ts.map +1 -1
- package/types/route/stsrouterbase.d.ts +2 -2
- package/types/route/stsrouterbase.d.ts.map +1 -1
- package/types/stsexpressserver.d.ts +2 -2
- package/types/stsexpressserver.d.ts.map +1 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF
|
|
2
|
-
import chalk from
|
|
3
|
-
import { TinyEmitter } from
|
|
4
|
-
import { randomUUID } from
|
|
5
|
-
import onHeaders from
|
|
2
|
+
import chalk from "chalk"; // Note: Do NOT upgrade beyond 4.1.2 as the ESM version (5.0.0+) breaks this entire codebase
|
|
3
|
+
import { TinyEmitter } from "tiny-emitter";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
import onHeaders from "on-headers";
|
|
6
6
|
export var ServerNetworkMiddlewareEventName;
|
|
7
7
|
(function (ServerNetworkMiddlewareEventName) {
|
|
8
|
-
ServerNetworkMiddlewareEventName["UpdateInstrument_SERVER_NET_VAL"] = "UpdateInstrument_SERVER_NET_VAL";
|
|
8
|
+
ServerNetworkMiddlewareEventName["UpdateInstrument_SERVER_NET_VAL"] = "UpdateInstrument_SERVER_NET_VAL";
|
|
9
9
|
})(ServerNetworkMiddlewareEventName || (ServerNetworkMiddlewareEventName = {}));
|
|
10
10
|
export class ServerNetworkMiddleware {
|
|
11
11
|
options;
|
|
12
12
|
#tinyEmitter = new TinyEmitter();
|
|
13
13
|
#socketCollection = {};
|
|
14
|
-
#id =
|
|
14
|
+
#id = "";
|
|
15
15
|
constructor(options) {
|
|
16
16
|
this.options = options;
|
|
17
17
|
}
|
|
@@ -37,26 +37,32 @@ export class ServerNetworkMiddleware {
|
|
|
37
37
|
workingSocketRecord.eventName = eventName;
|
|
38
38
|
workingSocketRecord.currentBytesRead = req.socket.bytesRead;
|
|
39
39
|
workingSocketRecord.currentBytesWritten = req.socket.bytesWritten;
|
|
40
|
-
workingSocketRecord.requestBytesRead =
|
|
41
|
-
|
|
40
|
+
workingSocketRecord.requestBytesRead =
|
|
41
|
+
workingSocketRecord.currentBytesRead -
|
|
42
|
+
workingSocketRecord.lastBytesRead;
|
|
43
|
+
workingSocketRecord.requestBytesWritten =
|
|
44
|
+
workingSocketRecord.currentBytesWritten -
|
|
45
|
+
workingSocketRecord.lastBytesWritten;
|
|
42
46
|
//this.#LogDebugMessage(chalk.gray(`totalBytesRead: [${workingSocketRecord.id}] [${workingSocketRecord.originalUrl}] [${eventName}] [${workingSocketRecord.requestBytesRead}]`));
|
|
43
47
|
//this.#LogDebugMessage(chalk.gray(`totalBytesWritten: [${workingSocketRecord.id}] [${workingSocketRecord.originalUrl}] [${eventName}] [${workingSocketRecord.requestBytesWritten}]`));
|
|
44
48
|
const workingSocketEventRecord = { ...workingSocketRecord };
|
|
45
49
|
delete workingSocketEventRecord.socket;
|
|
46
50
|
this.#LogSillyMessage(chalk.gray(`Sending event: [${JSON.stringify(workingSocketEventRecord)}]`));
|
|
47
51
|
this.#tinyEmitter.emit(ServerNetworkMiddlewareEventName.UpdateInstrument_SERVER_NET_VAL, workingSocketEventRecord);
|
|
48
|
-
workingSocketRecord.lastBytesRead =
|
|
49
|
-
|
|
52
|
+
workingSocketRecord.lastBytesRead =
|
|
53
|
+
workingSocketRecord.currentBytesRead;
|
|
54
|
+
workingSocketRecord.lastBytesWritten =
|
|
55
|
+
workingSocketRecord.currentBytesWritten;
|
|
50
56
|
};
|
|
51
57
|
#GetRequestContentSize = (req) => {
|
|
52
58
|
try {
|
|
53
59
|
let contentLength = 0;
|
|
54
|
-
if (req[
|
|
55
|
-
contentLength = req[
|
|
60
|
+
if (req["_contentLength"]) {
|
|
61
|
+
contentLength = req["_contentLength"];
|
|
56
62
|
}
|
|
57
63
|
else {
|
|
58
|
-
if (req.headers[
|
|
59
|
-
contentLength = parseInt(req.headers[
|
|
64
|
+
if (req.headers["content-length"]) {
|
|
65
|
+
contentLength = parseInt(req.headers["content-length"]);
|
|
60
66
|
}
|
|
61
67
|
}
|
|
62
68
|
return contentLength;
|
|
@@ -81,25 +87,26 @@ export class ServerNetworkMiddleware {
|
|
|
81
87
|
requestBytesRead: 0,
|
|
82
88
|
requestBytesWritten: 0,
|
|
83
89
|
originalUrl: req.originalUrl,
|
|
84
|
-
eventName:
|
|
90
|
+
eventName: "",
|
|
85
91
|
};
|
|
86
|
-
this.#socketCollection[workingSocketRecord.id] =
|
|
92
|
+
this.#socketCollection[workingSocketRecord.id] =
|
|
93
|
+
workingSocketRecord;
|
|
87
94
|
this.#LogSillyMessage(chalk.gray(`Adding new socket to recordset: ID: [${workingSocketRecord.id}], originalUrl: [${workingSocketRecord.originalUrl}]`));
|
|
88
|
-
workingSocketRecord.socket.on(
|
|
95
|
+
workingSocketRecord.socket.on("data", () => {
|
|
89
96
|
const socketRecord = this.GetSocketRecord(workingSocketRecord.socket);
|
|
90
97
|
if (socketRecord) {
|
|
91
98
|
this.#LogSillyMessage(chalk.gray(`Socket data event: ID: [${socketRecord.id}], originalUrl: [${socketRecord.originalUrl}]`));
|
|
92
|
-
this.UpdateNetworkStats(socketRecord,
|
|
99
|
+
this.UpdateNetworkStats(socketRecord, "socket_data", req);
|
|
93
100
|
}
|
|
94
101
|
else {
|
|
95
102
|
this.#LogSillyMessage(chalk.magenta(`Socket data event: Could not find socket within recordset`));
|
|
96
103
|
}
|
|
97
104
|
});
|
|
98
|
-
workingSocketRecord.socket.on(
|
|
105
|
+
workingSocketRecord.socket.on("close", () => {
|
|
99
106
|
const socketRecord = this.GetSocketRecord(workingSocketRecord.socket);
|
|
100
107
|
if (socketRecord) {
|
|
101
108
|
this.#LogSillyMessage(chalk.gray(`Socket close event: ID: [${socketRecord.id}], originalUrl: [${socketRecord.originalUrl}]`));
|
|
102
|
-
this.UpdateNetworkStats(socketRecord,
|
|
109
|
+
this.UpdateNetworkStats(socketRecord, "socket_close", req);
|
|
103
110
|
delete this.#socketCollection[socketRecord.id];
|
|
104
111
|
this.#LogSillyMessage(chalk.gray(`Socket removed from recordset: ID: [${socketRecord.id}], originalUrl: [${socketRecord.originalUrl}]`));
|
|
105
112
|
}
|
|
@@ -107,11 +114,11 @@ export class ServerNetworkMiddleware {
|
|
|
107
114
|
this.#LogSillyMessage(chalk.magenta(`Socket close event: Could not find socket within recordset`));
|
|
108
115
|
}
|
|
109
116
|
});
|
|
110
|
-
workingSocketRecord.socket.on(
|
|
117
|
+
workingSocketRecord.socket.on("end", () => {
|
|
111
118
|
const socketRecord = this.GetSocketRecord(workingSocketRecord.socket);
|
|
112
119
|
if (socketRecord) {
|
|
113
120
|
this.#LogSillyMessage(chalk.gray(`Socket end event: ID: [${socketRecord.id}], originalUrl: [${socketRecord.originalUrl}]`));
|
|
114
|
-
this.UpdateNetworkStats(socketRecord,
|
|
121
|
+
this.UpdateNetworkStats(socketRecord, "socket_end", req);
|
|
115
122
|
}
|
|
116
123
|
else {
|
|
117
124
|
this.#LogSillyMessage(chalk.magenta(`Socket end event: Could not find socket within recordset`));
|
|
@@ -122,38 +129,38 @@ export class ServerNetworkMiddleware {
|
|
|
122
129
|
// From brief observations, this appears to be about 80 bytes short from what is reported by the socket writtenBytes.
|
|
123
130
|
onHeaders(res, () => {
|
|
124
131
|
let contentLength = 0;
|
|
125
|
-
if (res[
|
|
126
|
-
contentLength = res[
|
|
132
|
+
if (res["_contentLength"]) {
|
|
133
|
+
contentLength = res["_contentLength"];
|
|
127
134
|
}
|
|
128
135
|
else {
|
|
129
|
-
if (res.hasHeader(
|
|
130
|
-
contentLength = parseInt(res.getHeader(
|
|
136
|
+
if (res.hasHeader("content-length")) {
|
|
137
|
+
contentLength = parseInt(res.getHeader("content-length"));
|
|
131
138
|
}
|
|
132
139
|
}
|
|
133
140
|
// Ensure that the client does NOT cache the response
|
|
134
|
-
res.setHeader(
|
|
135
|
-
res.setHeader(
|
|
136
|
-
res.setHeader(
|
|
141
|
+
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1
|
|
142
|
+
res.setHeader("Pragma", "no-cache"); // HTTP 1.0
|
|
143
|
+
res.setHeader("Expires", "0"); // Proxies
|
|
137
144
|
const headerLength = JSON.stringify(res.getHeaders()).length;
|
|
138
145
|
const totalSize = contentLength + headerLength;
|
|
139
146
|
this.#LogSillyMessage(chalk.white.bgBlue(`contentLength: [${contentLength}], headerLength: [${headerLength}], total Size: [${totalSize}]`));
|
|
140
147
|
});
|
|
141
148
|
// This event is the one where bytesWritten is generally recorded
|
|
142
|
-
req.on(
|
|
149
|
+
req.on("end", () => {
|
|
143
150
|
const socketRecord = this.GetSocketRecord(req.socket);
|
|
144
151
|
if (socketRecord) {
|
|
145
152
|
this.#LogSillyMessage(chalk.gray(`Request end event: ID: [${socketRecord.id}], originalUrl: [${socketRecord.originalUrl}]`));
|
|
146
|
-
this.UpdateNetworkStats(socketRecord,
|
|
153
|
+
this.UpdateNetworkStats(socketRecord, "req_end", req);
|
|
147
154
|
}
|
|
148
155
|
else {
|
|
149
156
|
this.#LogSillyMessage(chalk.magenta(`Request end event: Could not find socket within recordset`));
|
|
150
157
|
}
|
|
151
158
|
});
|
|
152
|
-
req.on(
|
|
159
|
+
req.on("close", () => {
|
|
153
160
|
const socketRecord = this.GetSocketRecord(req.socket);
|
|
154
161
|
if (socketRecord) {
|
|
155
162
|
this.#LogSillyMessage(chalk.gray(`Request close event: ID: [${socketRecord.id}], originalUrl: [${socketRecord.originalUrl}]`));
|
|
156
|
-
this.UpdateNetworkStats(socketRecord,
|
|
163
|
+
this.UpdateNetworkStats(socketRecord, "req_close", req);
|
|
157
164
|
}
|
|
158
165
|
else {
|
|
159
166
|
this.#LogSillyMessage(chalk.magenta(`Request close event: Could not find socket within recordset`));
|
|
@@ -185,7 +192,7 @@ export class ServerNetworkMiddleware {
|
|
|
185
192
|
const inTotal = inHeadersLength + inContentLength;
|
|
186
193
|
this.#LogSillyMessage(chalk.white.bgGray(`inHeadersLength: [${inHeadersLength}], inContentLength: [${inContentLength}], inTotal: [${inTotal}]`));
|
|
187
194
|
// This event is the one where bytesRead is generally recorded
|
|
188
|
-
this.UpdateNetworkStats(workingSocketRecord,
|
|
195
|
+
this.UpdateNetworkStats(workingSocketRecord, "middleware", req);
|
|
189
196
|
next();
|
|
190
197
|
};
|
|
191
198
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverNetworkMiddleware.js","sourceRoot":"","sources":["../../src/middleware/serverNetworkMiddleware.ts"],"names":[],"mappings":"AAAA,wFAAwF,
|
|
1
|
+
{"version":3,"file":"serverNetworkMiddleware.js","sourceRoot":"","sources":["../../src/middleware/serverNetworkMiddleware.ts"],"names":[],"mappings":"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"}
|
package/dist/network.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import os from
|
|
1
|
+
import os from "os";
|
|
2
2
|
export function GetNetworkInterfaces() {
|
|
3
3
|
const nets = os.networkInterfaces();
|
|
4
4
|
const results = {};
|
|
@@ -6,7 +6,7 @@ export function GetNetworkInterfaces() {
|
|
|
6
6
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
7
|
for (const net of nets[name]) {
|
|
8
8
|
// Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
|
|
9
|
-
if (net.family ===
|
|
9
|
+
if (net.family === "IPv4" && !net.internal) {
|
|
10
10
|
if (!results[name]) {
|
|
11
11
|
results[name] = [];
|
|
12
12
|
}
|
package/dist/network.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network.js","sourceRoot":"","sources":["../src/network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"network.js","sourceRoot":"","sources":["../src/network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAIpB,MAAM,UAAU,oBAAoB;IAChC,MAAM,IAAI,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC;IACpC,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,8DAA8D;QAC9D,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAQ,EAAE,CAAC;YAClC,6DAA6D;YAC7D,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;gBACzC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjB,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACvB,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACpC,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,wBAAwB;IACpC,MAAM,IAAI,GAAsB,oBAAoB,EAAE,CAAC;IACvD,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,GAAG,GAAa,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjB,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM;QACV,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AACpB,CAAC"}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
-
import si from
|
|
4
|
-
import axios from
|
|
5
|
-
import cluster from
|
|
6
|
-
import chalk from
|
|
7
|
-
import express from
|
|
8
|
-
import { setupPrimary } from
|
|
9
|
-
import { createServer as createServerHttps } from
|
|
10
|
-
import { createServer } from
|
|
11
|
-
import { AggregatorRegistry } from
|
|
12
|
-
import { goptions } from
|
|
13
|
-
import { Gauge, GaugeTypes } from
|
|
14
|
-
import { ProcessBase } from
|
|
15
|
-
import { IPCMessageCommand } from
|
|
16
|
-
import { STSTransportLoggerWinston } from
|
|
17
|
-
import { Sleep, STSAxiosConfig, createAgentManager } from
|
|
18
|
-
import http from
|
|
19
|
-
import https from
|
|
3
|
+
import si from "systeminformation"; // https://systeminformation.io/
|
|
4
|
+
import axios from "axios";
|
|
5
|
+
import cluster from "node:cluster";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import express from "express";
|
|
8
|
+
import { setupPrimary } from "@socket.io/cluster-adapter";
|
|
9
|
+
import { createServer as createServerHttps } from "node:https";
|
|
10
|
+
import { createServer } from "node:http";
|
|
11
|
+
import { AggregatorRegistry } from "prom-client";
|
|
12
|
+
import { goptions } from "@nsshunt/stsconfig";
|
|
13
|
+
import { Gauge, GaugeTypes, } from "@nsshunt/stsobservability";
|
|
14
|
+
import { ProcessBase } from "./processbase.js";
|
|
15
|
+
import { IPCMessageCommand } from "./../commonTypes.js";
|
|
16
|
+
import { STSTransportLoggerWinston } from "./../logger/stsTransportLoggerWinston.js";
|
|
17
|
+
import { Sleep, STSAxiosConfig, createAgentManager, } from "@nsshunt/stsutils";
|
|
18
|
+
import http from "node:http";
|
|
19
|
+
import https from "node:https";
|
|
20
20
|
//import { GetFirstNetworkInterface } from './network';
|
|
21
21
|
export class MasterProcessBase extends ProcessBase {
|
|
22
22
|
//static WORKER_MESSAGE_EVENT = 'sts_worker_message_event';
|
|
23
23
|
#masterProcessExitTime = goptions.masterProcessExitTime;
|
|
24
24
|
#childProcessExitTime = goptions.childProcessExitTime;
|
|
25
25
|
#siValueObject = {
|
|
26
|
-
currentLoad:
|
|
26
|
+
currentLoad: "currentLoad",
|
|
27
27
|
};
|
|
28
28
|
#httpServer = null; // Prometheus cluster server. See https://github.com/siimon/prom-client/blob/master/example/cluster.js
|
|
29
29
|
#metricsServer = null;
|
|
@@ -42,14 +42,14 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
42
42
|
maxSockets: goptions.maxSockets,
|
|
43
43
|
maxTotalSockets: goptions.maxTotalSockets,
|
|
44
44
|
timeout: goptions.timeout,
|
|
45
|
-
rejectUnauthorized: goptions.isProduction // Allows self-signed certificates if non-production
|
|
45
|
+
rejectUnauthorized: goptions.isProduction, // Allows self-signed certificates if non-production
|
|
46
46
|
},
|
|
47
47
|
httpAgentFactory(options) {
|
|
48
48
|
return new http.Agent(options);
|
|
49
49
|
},
|
|
50
50
|
httpsAgentFactory(options) {
|
|
51
51
|
return new https.Agent(options);
|
|
52
|
-
}
|
|
52
|
+
},
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
#LogErrorMessage(message) {
|
|
@@ -60,21 +60,24 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
60
60
|
}
|
|
61
61
|
CollectAdditionalTelemetry() {
|
|
62
62
|
try {
|
|
63
|
-
si.get(this.#siValueObject).then(data => {
|
|
63
|
+
si.get(this.#siValueObject).then((data) => {
|
|
64
64
|
this.UpdateInstrument(Gauge.CPU_SYSTEM_LOAD_GAUGE, {
|
|
65
|
-
val: data.currentLoad.currentLoad
|
|
65
|
+
val: data.currentLoad.currentLoad,
|
|
66
66
|
});
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
}
|
|
69
|
+
catch (error) { }
|
|
71
70
|
}
|
|
72
71
|
GetAdditionalInstruments() {
|
|
73
72
|
return [
|
|
74
|
-
[
|
|
73
|
+
[
|
|
74
|
+
Gauge.CPU_SYSTEM_LOAD_GAUGE,
|
|
75
|
+
GaugeTypes.INSTRUMENT_GAUGE,
|
|
76
|
+
{
|
|
75
77
|
interval: goptions.instrumentationObservationInterval,
|
|
76
|
-
sampleSize: goptions.instrumentationTimeWindow
|
|
77
|
-
}
|
|
78
|
+
sampleSize: goptions.instrumentationTimeWindow,
|
|
79
|
+
},
|
|
80
|
+
],
|
|
78
81
|
];
|
|
79
82
|
}
|
|
80
83
|
/**
|
|
@@ -90,8 +93,8 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
90
93
|
}
|
|
91
94
|
}
|
|
92
95
|
#InitCluster = () => {
|
|
93
|
-
cluster.on(
|
|
94
|
-
this.emit(
|
|
96
|
+
cluster.on("listening", (worker, address) => {
|
|
97
|
+
this.emit("clusterListening", worker, address);
|
|
95
98
|
let allListening = true;
|
|
96
99
|
for (const worker of Object.values(cluster.workers)) {
|
|
97
100
|
if (worker?.isConnected) {
|
|
@@ -101,7 +104,7 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
101
104
|
}
|
|
102
105
|
if (allListening) {
|
|
103
106
|
this.LogInfoMessage(`Service instance started.`);
|
|
104
|
-
this.emit(
|
|
107
|
+
this.emit("allListening");
|
|
105
108
|
}
|
|
106
109
|
});
|
|
107
110
|
};
|
|
@@ -110,24 +113,24 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
110
113
|
this.#metricsServer = express();
|
|
111
114
|
this.#aggregatorRegistry = new AggregatorRegistry();
|
|
112
115
|
switch (goptions.STSServerType) {
|
|
113
|
-
case
|
|
116
|
+
case "EXPRESS_TLS":
|
|
114
117
|
{
|
|
115
118
|
const options = {
|
|
116
119
|
key: fs.readFileSync(this.options.httpsServerKeyPath),
|
|
117
|
-
cert: fs.readFileSync(this.options.httpsServerCertificatePath)
|
|
120
|
+
cert: fs.readFileSync(this.options.httpsServerCertificatePath),
|
|
118
121
|
};
|
|
119
122
|
this.#httpServer = createServerHttps(options, this.#metricsServer);
|
|
120
123
|
}
|
|
121
124
|
break;
|
|
122
|
-
case
|
|
125
|
+
case "EXPRESS": {
|
|
123
126
|
this.#httpServer = createServer(this.#metricsServer);
|
|
124
127
|
}
|
|
125
128
|
}
|
|
126
129
|
//this.#httpServer.maxConnections = 50;
|
|
127
|
-
this.#metricsServer.get(
|
|
130
|
+
this.#metricsServer.get("/cluster_metrics", async (req, res) => {
|
|
128
131
|
try {
|
|
129
132
|
const metrics = await this.#aggregatorRegistry.clusterMetrics();
|
|
130
|
-
res.set(
|
|
133
|
+
res.set("Content-Type", this.#aggregatorRegistry.contentType);
|
|
131
134
|
res.send(metrics);
|
|
132
135
|
}
|
|
133
136
|
catch (ex) {
|
|
@@ -141,10 +144,12 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
141
144
|
//@@httpServer.listen('/tmp/stsrest01.sock').on('listening', () =>
|
|
142
145
|
//@@httpServer.listen('/var/run/sts/stsrest01.sock').on('listening', () =>
|
|
143
146
|
//@@httpServer.listen('/var/lib/sts/stsrest01.sock').on('listening', () =>
|
|
144
|
-
this.#httpServer
|
|
147
|
+
this.#httpServer
|
|
148
|
+
.listen(this.options.prometheusClusterPort, () => {
|
|
145
149
|
//@@chmodSync(this.options.port, 511);
|
|
146
|
-
})
|
|
147
|
-
|
|
150
|
+
})
|
|
151
|
+
.on("listening", () => {
|
|
152
|
+
this.emit("prometheusScrapesListening", `${this.options.endpoint}:${this.options.prometheusClusterPort}/metrics`, this.options.endpoint, this.options.prometheusClusterPort);
|
|
148
153
|
this.LogInfoMessage(`Prometheus scrapes ready and live on ${this.options.endpoint}:${this.options.prometheusClusterPort}/metrics`);
|
|
149
154
|
});
|
|
150
155
|
}
|
|
@@ -163,7 +168,7 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
163
168
|
// We use port rather than hostport becuase this test going outside the service and comes back in as a regular client
|
|
164
169
|
const url = `${this.options.endpoint}:${this.options.port}${this.options.apiRoot}/latency`;
|
|
165
170
|
try {
|
|
166
|
-
retVal = await axios(new STSAxiosConfig(url,
|
|
171
|
+
retVal = await axios(new STSAxiosConfig(url, "get")
|
|
167
172
|
.withDefaultHeaders()
|
|
168
173
|
.withAgentManager(this.#agentManager).config);
|
|
169
174
|
if (retVal.status !== 200) {
|
|
@@ -187,14 +192,13 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
187
192
|
timeInMs = (end[0] * 1000000000 + end[1]) / 1000000;
|
|
188
193
|
timeInMs = parseFloat(timeInMs.toFixed(4));
|
|
189
194
|
this.UpdateInstrument(Gauge.LATENCY_HISTOGRAM_GAUGE, {
|
|
190
|
-
val: timeInMs
|
|
195
|
+
val: timeInMs,
|
|
191
196
|
});
|
|
192
197
|
this.UpdateInstrument(Gauge.LATENCY_GAUGE, {
|
|
193
|
-
val: timeInMs
|
|
198
|
+
val: timeInMs,
|
|
194
199
|
});
|
|
195
200
|
};
|
|
196
201
|
SetupServer = async () => {
|
|
197
|
-
this.SetupInstrumentation();
|
|
198
202
|
setTimeout(() => {
|
|
199
203
|
this.SetupServerEx();
|
|
200
204
|
}, 100);
|
|
@@ -204,8 +208,12 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
204
208
|
if (cluster.workers && cluster.workers[id]) {
|
|
205
209
|
const worker = cluster.workers[id];
|
|
206
210
|
if (worker.process) {
|
|
207
|
-
this.LogInfoMessage(chalk.grey(`Sending terminate message `) +
|
|
208
|
-
|
|
211
|
+
this.LogInfoMessage(chalk.grey(`Sending terminate message `) +
|
|
212
|
+
chalk.yellow(`(initiated by ${signal})`) +
|
|
213
|
+
chalk.grey(` for worker PID: ${worker.process.pid}`));
|
|
214
|
+
const command = killProcess
|
|
215
|
+
? "TerminateAndKill"
|
|
216
|
+
: "Terminate";
|
|
209
217
|
try {
|
|
210
218
|
worker.send({ command });
|
|
211
219
|
//worker.process.send( { command } );
|
|
@@ -233,8 +241,9 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
233
241
|
};
|
|
234
242
|
KillWorker = (id, signal = "SIGTERM", options, killProcess, allowKillAll) => {
|
|
235
243
|
try {
|
|
236
|
-
if (allowKillAll ||
|
|
237
|
-
|
|
244
|
+
if (allowKillAll ||
|
|
245
|
+
Object.keys(cluster.workers).length > 1) {
|
|
246
|
+
if (id.localeCompare("0") === 0) {
|
|
238
247
|
const keys = Object.keys(cluster.workers);
|
|
239
248
|
for (let i = keys.length - 1; i > 0; i--) {
|
|
240
249
|
// Kill the last one added (assumed node keeps them in order)
|
|
@@ -268,7 +277,7 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
268
277
|
const logPrefix = `MasterProcessBase:KillWorkers():${process.pid}:`;
|
|
269
278
|
try {
|
|
270
279
|
this.LogInfoMessage(`${logPrefix} Killing Workers.`);
|
|
271
|
-
const keepOneAlive =
|
|
280
|
+
const keepOneAlive = keepOne ? keepOne : false;
|
|
272
281
|
let skippedFirst = false;
|
|
273
282
|
const sortedIdList = [];
|
|
274
283
|
for (const id in cluster.workers) {
|
|
@@ -290,7 +299,7 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
290
299
|
#UpdateWorkersInstrument = () => {
|
|
291
300
|
setTimeout(() => {
|
|
292
301
|
this.UpdateInstrument(Gauge.CORE_COUNT_GAUGE, {
|
|
293
|
-
val: this.#workers
|
|
302
|
+
val: this.#workers,
|
|
294
303
|
});
|
|
295
304
|
}, 2000);
|
|
296
305
|
};
|
|
@@ -321,7 +330,7 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
321
330
|
case IPCMessageCommand.AddWorker: {
|
|
322
331
|
const workerId = this.AddWorker(iPCMessagePayload.requestDetail?.options);
|
|
323
332
|
iPCMessagePayload.responseDetail = {
|
|
324
|
-
workerId
|
|
333
|
+
workerId,
|
|
325
334
|
};
|
|
326
335
|
return iPCMessagePayload;
|
|
327
336
|
}
|
|
@@ -331,7 +340,7 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
331
340
|
this.#LogDebugMessage(chalk.yellow(` Killed worker with id: [${workerId}]`));
|
|
332
341
|
iPCMessagePayload.responseDetail = {
|
|
333
342
|
workerId,
|
|
334
|
-
workerKilled
|
|
343
|
+
workerKilled,
|
|
335
344
|
};
|
|
336
345
|
return iPCMessagePayload;
|
|
337
346
|
}
|
|
@@ -342,7 +351,7 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
342
351
|
delete safeOptions.expressServerRouteFactory;
|
|
343
352
|
//this.#LogDebugMessage(chalk.yellow(` Safe options: [${JSON.stringify(safeOptions)}]`));
|
|
344
353
|
iPCMessagePayload.responseDetail = {
|
|
345
|
-
safeOptions
|
|
354
|
+
safeOptions,
|
|
346
355
|
};
|
|
347
356
|
return iPCMessagePayload;
|
|
348
357
|
}
|
|
@@ -359,9 +368,9 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
359
368
|
// Remove the assigned loggers (this will need to be re-created in the worker thread)
|
|
360
369
|
delete tempOptions.logger;
|
|
361
370
|
delete tempOptions.publisherLogger;
|
|
362
|
-
workerEnv[
|
|
371
|
+
workerEnv["STS_GSD_SII"] = JSON.stringify(tempOptions);
|
|
363
372
|
if (spawnWorkerOptions) {
|
|
364
|
-
workerEnv[
|
|
373
|
+
workerEnv["STS_GSD_OPTIONS"] = JSON.stringify(spawnWorkerOptions);
|
|
365
374
|
}
|
|
366
375
|
/*
|
|
367
376
|
// https://nodejs.org/api/cluster.html#clustersetupprimarysettings
|
|
@@ -377,8 +386,8 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
377
386
|
*/
|
|
378
387
|
const worker = cluster.fork(workerEnv);
|
|
379
388
|
this.IncWorkers();
|
|
380
|
-
worker.on(
|
|
381
|
-
this.emit(
|
|
389
|
+
worker.on("exit", (code, signal) => {
|
|
390
|
+
this.emit("workerExit", code, signal);
|
|
382
391
|
if (signal) {
|
|
383
392
|
this.LogInfoMessage(`Worker: ${worker.process.pid} was killed by signal: ${signal}`);
|
|
384
393
|
}
|
|
@@ -389,8 +398,8 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
389
398
|
this.LogInfoMessage(`Worker: ${worker.process.pid} exited successfully, code: ${code}, signal: ${signal}`);
|
|
390
399
|
}
|
|
391
400
|
});
|
|
392
|
-
worker.on(
|
|
393
|
-
this.emit(
|
|
401
|
+
worker.on("message", async (payload) => {
|
|
402
|
+
this.emit("workerMessage", worker.id, payload);
|
|
394
403
|
// Only handle request/response message types here ...
|
|
395
404
|
if (payload.requestResponse) {
|
|
396
405
|
const iPCMessagePayload = payload;
|
|
@@ -403,17 +412,18 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
403
412
|
this.#WorkerMessageEvent(worker.id, payload);
|
|
404
413
|
}
|
|
405
414
|
});
|
|
406
|
-
worker.on(
|
|
407
|
-
this.emit(
|
|
415
|
+
worker.on("error", (error) => {
|
|
416
|
+
this.emit("workerError", error);
|
|
408
417
|
const message = chalk.red(`#SpawnWorker():worker.on('error'): Error: [${error}]`);
|
|
409
418
|
this.LogErrorMessage(message);
|
|
410
419
|
});
|
|
411
|
-
this.emit(
|
|
420
|
+
this.emit("workerAdded", worker.id);
|
|
412
421
|
return worker.id;
|
|
413
422
|
};
|
|
414
423
|
MasterStarted() {
|
|
424
|
+
// eslint-disable @typescript-eslint/no-empty-function
|
|
415
425
|
const transport = new STSTransportLoggerWinston({
|
|
416
|
-
stsApp: this
|
|
426
|
+
stsApp: this,
|
|
417
427
|
});
|
|
418
428
|
setTimeout(() => {
|
|
419
429
|
this.options.logger.add(transport);
|
|
@@ -459,22 +469,22 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
459
469
|
this.#SpawnWorker();
|
|
460
470
|
}
|
|
461
471
|
this.#InitCluster();
|
|
462
|
-
cluster.on(
|
|
463
|
-
this.emit(
|
|
472
|
+
cluster.on("listening", (worker, address) => {
|
|
473
|
+
this.emit("clusterListening", worker, address);
|
|
464
474
|
this.LogInfoMessage(`Worker process ${worker.process.pid} is listening at address: ${JSON.stringify(address)}`);
|
|
465
475
|
});
|
|
466
476
|
//Setting up lifecycle event listeners for worker processes
|
|
467
|
-
cluster.on(
|
|
468
|
-
this.emit(
|
|
477
|
+
cluster.on("online", (worker) => {
|
|
478
|
+
this.emit("clusterOnline", worker);
|
|
469
479
|
this.LogInfoMessage(`Worker process ${worker.process.pid} is online`);
|
|
470
480
|
});
|
|
471
|
-
cluster.on(
|
|
472
|
-
this.emit(
|
|
473
|
-
if ((code !== null && code === 0) ||
|
|
481
|
+
cluster.on("exit", (worker, code, signal) => {
|
|
482
|
+
this.emit("clusterExit", worker, code, signal);
|
|
483
|
+
if ((code !== null && code === 0) || signal === "SIGINT") {
|
|
474
484
|
this.LogInfoMessage(chalk.green(`Process ${worker.process.pid} terminated gracefully with code: ${code}, signal: ${signal}`));
|
|
475
485
|
this.DecWorkers();
|
|
476
486
|
}
|
|
477
|
-
else if ((code !== null && code === 15) ||
|
|
487
|
+
else if ((code !== null && code === 15) || signal === "SIGTERM") {
|
|
478
488
|
this.DecWorkers();
|
|
479
489
|
this.LogInfoMessage(chalk.red(`Process ${worker.process.pid} terminated with code: ${code}, signal: ${signal}`));
|
|
480
490
|
}
|
|
@@ -483,7 +493,7 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
483
493
|
this.LogInfoMessage(chalk.red(`worker ${worker.process.pid} died`));
|
|
484
494
|
this.LogInfoMessage(chalk.red(`code: ${code}`));
|
|
485
495
|
this.LogInfoMessage(chalk.red(`signal: ${signal}`));
|
|
486
|
-
this.LogInfoMessage(chalk.red(
|
|
496
|
+
this.LogInfoMessage(chalk.red("process terminated in an error state"));
|
|
487
497
|
if (goptions.respawnOnFail === true) {
|
|
488
498
|
this.LogInfoMessage(chalk.magenta(`Attemping to respawn worker`));
|
|
489
499
|
this.#SpawnWorker();
|
|
@@ -537,16 +547,16 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
537
547
|
this.LogInfoMessage(`${logPrefix} Process already terminating.`);
|
|
538
548
|
}
|
|
539
549
|
};
|
|
540
|
-
process.on(
|
|
541
|
-
this.emit(
|
|
542
|
-
await Terminate(
|
|
550
|
+
process.on("SIGINT", async () => {
|
|
551
|
+
this.emit("processSigint");
|
|
552
|
+
await Terminate("SIGINT");
|
|
543
553
|
});
|
|
544
|
-
process.on(
|
|
545
|
-
this.emit(
|
|
546
|
-
await Terminate(
|
|
554
|
+
process.on("SIGTERM", async () => {
|
|
555
|
+
this.emit("processSigterm");
|
|
556
|
+
await Terminate("SIGTERM");
|
|
547
557
|
});
|
|
548
|
-
process.on(
|
|
549
|
-
this.emit(
|
|
558
|
+
process.on("exit", (code) => {
|
|
559
|
+
this.emit("processExit", code);
|
|
550
560
|
if (code === 0) {
|
|
551
561
|
this.LogInfoMessage(chalk.green(`Main Process: ${process.pid} terminated gracefully with code: ${code}`));
|
|
552
562
|
}
|
|
@@ -567,7 +577,10 @@ export class MasterProcessBase extends ProcessBase {
|
|
|
567
577
|
for (const id in cluster.workers) {
|
|
568
578
|
try {
|
|
569
579
|
//@@this.LogInfoMessage(chalk.gray(`Sending message to worker PID: ${cluster.workers[id].process.pid}`));
|
|
570
|
-
cluster.workers[id].process.send({
|
|
580
|
+
cluster.workers[id].process.send({
|
|
581
|
+
command: command,
|
|
582
|
+
data: data,
|
|
583
|
+
});
|
|
571
584
|
}
|
|
572
585
|
catch (error) {
|
|
573
586
|
//@@this.LogInfoMessage(error);
|