@nsshunt/stsappframework 3.1.130 → 3.1.131
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/ipcMessageHandler.js +4 -2
- package/dist/ipcMessageHandler.js.map +1 -1
- package/dist/ipcMessageManager.js +32 -4
- package/dist/ipcMessageManager.js.map +1 -1
- package/dist/ipcMessageProcessorPrimary.js +2 -1
- package/dist/ipcMessageProcessorPrimary.js.map +1 -1
- package/dist/ipcMessageProcessorWorker.js +2 -1
- package/dist/ipcMessageProcessorWorker.js.map +1 -1
- package/dist/redisMessageHandler.js +144 -6
- package/dist/redisMessageHandler.js.map +1 -1
- package/dist/redisMessageHandler.test.js +4 -2
- package/dist/redisMessageHandler.test.js.map +1 -1
- package/dist/testing/app.js +191 -37
- package/dist/testing/app.js.map +1 -1
- package/dist/workerprocessbase.js +107 -0
- package/dist/workerprocessbase.js.map +1 -1
- package/package.json +1 -1
- package/runtest2.sh +1 -1
- package/src/ipcMessageHandler.ts +4 -2
- package/src/ipcMessageManager.ts +40 -4
- package/src/ipcMessageProcessorPrimary.ts +2 -1
- package/src/ipcMessageProcessorWorker.ts +2 -1
- package/src/redisMessageHandler.test.ts +4 -2
- package/src/redisMessageHandler.ts +155 -6
- package/src/testing/app.ts +192 -17
- package/src/workerprocessbase.ts +123 -2
- package/types/ipcMessageHandler.d.ts.map +1 -1
- package/types/ipcMessageManager.d.ts +1 -0
- package/types/ipcMessageManager.d.ts.map +1 -1
- package/types/ipcMessageProcessorPrimary.d.ts.map +1 -1
- package/types/ipcMessageProcessorWorker.d.ts.map +1 -1
- package/types/redisMessageHandler.d.ts +2 -0
- package/types/redisMessageHandler.d.ts.map +1 -1
- package/types/workerprocessbase.d.ts +15 -0
- package/types/workerprocessbase.d.ts.map +1 -1
|
@@ -39,7 +39,8 @@ export class IPCMessageProcessorWorker {
|
|
|
39
39
|
},
|
|
40
40
|
messageReceiverStop: (options: any) => {
|
|
41
41
|
process.off('message', (payload) => this.#ipcMessageManager.ProcessMessage(payload, options));
|
|
42
|
-
}
|
|
42
|
+
},
|
|
43
|
+
groups: [ ]
|
|
43
44
|
}
|
|
44
45
|
this.#ipcMessageManager = new IPCMessageManager(ipcMessageManagerOptions);
|
|
45
46
|
}
|
|
@@ -39,7 +39,8 @@ describe.skip("Redis Message Handler Test", () =>
|
|
|
39
39
|
logger: defaultLogger,
|
|
40
40
|
role: 'SERVER',
|
|
41
41
|
redisUrl: ioRedisMessageProcessorUrl, // goptions.imRedisMessageProcessorUrl,
|
|
42
|
-
namespace: 'redistestingstsframework'
|
|
42
|
+
namespace: 'redistestingstsframework',
|
|
43
|
+
groups: [ ]
|
|
43
44
|
});
|
|
44
45
|
this.#r1.Start();
|
|
45
46
|
|
|
@@ -87,7 +88,8 @@ describe.skip("Redis Message Handler Test", () =>
|
|
|
87
88
|
logger: defaultLogger,
|
|
88
89
|
role: 'CLIENT',
|
|
89
90
|
redisUrl: ioRedisMessageProcessorUrl, // goptions.imRedisMessageProcessorUrl,
|
|
90
|
-
namespace: 'redistestingstsframework'
|
|
91
|
+
namespace: 'redistestingstsframework',
|
|
92
|
+
groups: [ ]
|
|
91
93
|
});
|
|
92
94
|
this.#r1.Start();
|
|
93
95
|
|
|
@@ -17,6 +17,7 @@ export interface IRedisAdminManagerOptions {
|
|
|
17
17
|
logger: ISTSLogger
|
|
18
18
|
role: 'SERVER' | 'CLIENT'
|
|
19
19
|
namespace: string
|
|
20
|
+
groups: string[]
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export interface IClientRecord {
|
|
@@ -24,6 +25,7 @@ export interface IClientRecord {
|
|
|
24
25
|
clientConnected: Date
|
|
25
26
|
pingCount: number
|
|
26
27
|
timeout: NodeJS.Timeout
|
|
28
|
+
groups: string[]
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
export interface IEventPayload {
|
|
@@ -78,19 +80,33 @@ export class RedisMessageHandler extends TinyEmitter {
|
|
|
78
80
|
if (this.#options.role.localeCompare('CLIENT') === 0) {
|
|
79
81
|
const ping = () => {
|
|
80
82
|
this.#pingTimeout = setTimeout(() => {
|
|
81
|
-
|
|
83
|
+
let group = '';
|
|
84
|
+
if (process.pid % 2 === 0) {
|
|
85
|
+
group = 'even';
|
|
86
|
+
} else {
|
|
87
|
+
group = 'odd';
|
|
88
|
+
}
|
|
89
|
+
//console.log(chalk.gray(`${process.pid}: emitting ping ...`))
|
|
90
|
+
this.emit('ping', {
|
|
91
|
+
id: this.#ipcMessageManager?.id,
|
|
92
|
+
groups: [
|
|
93
|
+
group
|
|
94
|
+
]
|
|
95
|
+
}, (response: any) => { });
|
|
82
96
|
ping();
|
|
83
97
|
}, 1000).unref();
|
|
84
98
|
}
|
|
85
99
|
ping();
|
|
86
100
|
} else {
|
|
87
|
-
this.on('ping', (
|
|
101
|
+
this.on('ping', (pingData: JSONObject, callback: any) => {
|
|
102
|
+
const { id, groups } = pingData;
|
|
88
103
|
if (this.#clients[id]) {
|
|
89
104
|
clearTimeout(this.#clients[id].timeout);
|
|
90
105
|
this.#clients[id].pingCount++;
|
|
91
106
|
this.#clients[id].timeout = setTimeout(() => {
|
|
92
107
|
delete this.#clients[id];
|
|
93
108
|
}, 2000);
|
|
109
|
+
this.#clients[id].groups = groups;
|
|
94
110
|
} else {
|
|
95
111
|
this.#clients[id] = {
|
|
96
112
|
id,
|
|
@@ -98,12 +114,17 @@ export class RedisMessageHandler extends TinyEmitter {
|
|
|
98
114
|
pingCount: 0,
|
|
99
115
|
timeout: setTimeout(() => {
|
|
100
116
|
delete this.#clients[id];
|
|
101
|
-
}, 2000)
|
|
117
|
+
}, 2000),
|
|
118
|
+
groups
|
|
102
119
|
}
|
|
103
120
|
}
|
|
121
|
+
//console.log(chalk.gray(` ${process.pid}: processed ping ...`))
|
|
104
122
|
callback('ok');
|
|
105
123
|
});
|
|
106
124
|
}
|
|
125
|
+
|
|
126
|
+
console.log(chalk.yellow(`RedisMessageHandler:constructor(): [${JSON.stringify(this.#options.groups)}]`));
|
|
127
|
+
|
|
107
128
|
}
|
|
108
129
|
|
|
109
130
|
#LogInfo(message: any) {
|
|
@@ -126,6 +147,7 @@ export class RedisMessageHandler extends TinyEmitter {
|
|
|
126
147
|
namespace: this.#options.namespace,
|
|
127
148
|
role: this.#options.role,
|
|
128
149
|
messageSender: this.#messageSender,
|
|
150
|
+
groups: this.#options.groups,
|
|
129
151
|
// This method is used to calculate if all responses have been received from multiple clients (broadcast)
|
|
130
152
|
// returns true/false.
|
|
131
153
|
ProcessResponseMessage: this.#ProcessResponseMessage,
|
|
@@ -166,16 +188,143 @@ export class RedisMessageHandler extends TinyEmitter {
|
|
|
166
188
|
return allFound;
|
|
167
189
|
}
|
|
168
190
|
|
|
191
|
+
console.log(chalk.grey(`${process.pid}: -->> *** <<-- #ProcessResponseMessage`));
|
|
169
192
|
let found = true;
|
|
193
|
+
|
|
194
|
+
// Sender role here is SERVER
|
|
195
|
+
|
|
196
|
+
console.log(chalk.yellow(`${process.pid}: Total Clients :-`));
|
|
197
|
+
Object.values(this.#clients).forEach(c => {
|
|
198
|
+
console.log(chalk.yellow(`${process.pid}: ${c.id} ${c.groups}`));
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
let requestGroup = null;
|
|
202
|
+
console.log(chalk.blue(`${process.pid}: Responses :-`));
|
|
203
|
+
for (const [responseId, response] of Object.entries(responses)) {
|
|
204
|
+
console.log(chalk.blue(`${process.pid}: client.id: [${responseId}] response payload: [${JSON.stringify(response.responsePayload)}]`));
|
|
205
|
+
if (response.requestPayload.args.length > 0 && response.requestPayload.args[0].group) {
|
|
206
|
+
requestGroup = response.requestPayload.args[0].group;
|
|
207
|
+
console.log(chalk.blue(`${process.pid}: Group Request: [${requestGroup}]`));
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (requestGroup) {
|
|
213
|
+
console.log(chalk.blue(`${process.pid}: Group Request`));
|
|
214
|
+
const clientsInGroup = Object.values(this.#clients).filter(c => {
|
|
215
|
+
if (c.groups.indexOf(requestGroup) === -1) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
return true;
|
|
219
|
+
});
|
|
220
|
+
console.log(chalk.blue(`${process.pid}: Clients in group: [${requestGroup}] :-`));
|
|
221
|
+
clientsInGroup.forEach(c => {
|
|
222
|
+
console.log(chalk.blue(`${process.pid}: ${c.id}`));
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
// Now make sure that all clients are in the responses
|
|
226
|
+
found = true;
|
|
227
|
+
clientsInGroup.forEach(c => {
|
|
228
|
+
if (!responses[c.id]) {
|
|
229
|
+
found = false;
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
console.log(chalk.blue(`${process.pid}: found (group) = [${found}]`));
|
|
233
|
+
} else {
|
|
234
|
+
console.log(chalk.blue(`${process.pid}: Non-Group Request`));
|
|
235
|
+
|
|
236
|
+
const clientsInGroup = Object.values(this.#clients)
|
|
237
|
+
console.log(chalk.blue(`${process.pid}: Clients in group (global list): [${requestGroup}] :-`));
|
|
238
|
+
clientsInGroup.forEach(c => {
|
|
239
|
+
console.log(chalk.blue(`${process.pid}: ${c.id}`));
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
// Now make sure that all clients are in the responses
|
|
243
|
+
found = true;
|
|
244
|
+
clientsInGroup.forEach(c => {
|
|
245
|
+
if (!responses[c.id]) {
|
|
246
|
+
found = false;
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
console.log(chalk.blue(`${process.pid}: found (non-group) = [${found}]`));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return found;
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
/*
|
|
256
|
+
|
|
257
|
+
|
|
170
258
|
Object.values(this.#clients).map(c => {
|
|
171
|
-
if (
|
|
172
|
-
|
|
259
|
+
if (found) {
|
|
260
|
+
// Check for group payloads
|
|
261
|
+
|
|
262
|
+
console.log(chalk.magenta(`${process.pid}: clients (from ping data)`));
|
|
263
|
+
for (const [key, value] of Object.entries(this.#clients)) {
|
|
264
|
+
console.log(chalk.magenta(`${process.pid}: ${key} = [${value.id} ${value.groups}]`))
|
|
265
|
+
}
|
|
266
|
+
console.log(chalk.blue(`${process.pid}: ${JSON.stringify(responses)}`));
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
if (responses[c.id]) {
|
|
270
|
+
console.log(chalk.blue(`${process.pid}: 1`));
|
|
271
|
+
if (responses[c.id].requestPayload) {
|
|
272
|
+
console.log(chalk.blue(`${process.pid}: 2`));
|
|
273
|
+
if (responses[c.id].requestPayload.args.length > 0) {
|
|
274
|
+
console.log(chalk.blue(`${process.pid}: 3`));
|
|
275
|
+
if (responses[c.id].requestPayload.args[0].group) {
|
|
276
|
+
console.log(chalk.blue(`${process.pid}: 4`));
|
|
277
|
+
console.log(chalk.magenta(`${process.pid}:requestPayload: [${JSON.stringify(responses[c.id].requestPayload.args[0].group )}]`))
|
|
278
|
+
const requestGroup = responses[c.id].requestPayload.args[0].group;
|
|
279
|
+
//const responseGroup = responses[c.id].responsePayload.args[0].group;
|
|
280
|
+
|
|
281
|
+
console.log(chalk.magenta(`${process.pid}: clients (from ping data)`));
|
|
282
|
+
Object.values(this.#clients).forEach(c => {
|
|
283
|
+
console.log(chalk.magenta(` ${c.groups}`))
|
|
284
|
+
})
|
|
285
|
+
console.log(chalk.magenta(`${process.pid}:`));
|
|
286
|
+
|
|
287
|
+
console.log(chalk.magenta(`${process.pid}: responses so far...`));
|
|
288
|
+
|
|
289
|
+
for (const [key, value] of Object.entries(responses)) {
|
|
290
|
+
console.log(chalk.magenta(`${process.pid}: client.id: [${key}] response payload: [${JSON.stringify(value.responsePayload)}]`));
|
|
291
|
+
}
|
|
292
|
+
console.log(chalk.magenta(`${process.pid}:`));
|
|
293
|
+
|
|
294
|
+
const clientsInGroup = Object.values(this.#clients).filter(c => {
|
|
295
|
+
const foundGroupIndex = c.groups.indexOf(requestGroup);
|
|
296
|
+
if (foundGroupIndex === -1) {
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
return true;
|
|
300
|
+
});
|
|
301
|
+
clientsInGroup.forEach(c => {
|
|
302
|
+
console.log(`${process.pid}:clientsInGroup: [${c.id}] groups: [${c.groups}]`);
|
|
303
|
+
if (!responses[c.id]) {
|
|
304
|
+
console.log(`${process.pid}: clientsInGroup - not found: [${c.id}]`);
|
|
305
|
+
found = false;
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
// Now check if all responses for completed group membership
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
} else {
|
|
313
|
+
if (!responses[c.id]) {
|
|
314
|
+
found = false;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
173
317
|
}
|
|
174
318
|
});
|
|
175
319
|
|
|
176
|
-
|
|
320
|
+
console.log(chalk.grey(`${process.pid}: ** Testing condition **`))
|
|
321
|
+
if (found === true) {
|
|
322
|
+
console.log(chalk.green(`${process.pid}:Found all messages - should return results`))
|
|
177
323
|
return true;
|
|
178
324
|
}
|
|
325
|
+
console.log(chalk.red(`${process.pid}:did not find all messages (yet) ...`))
|
|
326
|
+
return false;
|
|
327
|
+
*/
|
|
179
328
|
return false;
|
|
180
329
|
}
|
|
181
330
|
|
package/src/testing/app.ts
CHANGED
|
@@ -20,6 +20,9 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
20
20
|
import { RedisMessageHandler } from './../redisMessageHandler'
|
|
21
21
|
import { goptions } from '@nsshunt/stsconfig'
|
|
22
22
|
|
|
23
|
+
import si from 'systeminformation' // https://systeminformation.io/
|
|
24
|
+
import { GetFirstNetworkInterface } from './../network'
|
|
25
|
+
|
|
23
26
|
const sleepVal = 0;
|
|
24
27
|
const maxLoop = 100;
|
|
25
28
|
|
|
@@ -177,13 +180,97 @@ const StartTestWorker = () => {
|
|
|
177
180
|
}, 1000);
|
|
178
181
|
}
|
|
179
182
|
|
|
180
|
-
const iterations =
|
|
183
|
+
const iterations = 0;
|
|
181
184
|
const delay = 100;
|
|
182
185
|
|
|
186
|
+
const GetNumCPUs = async (): Promise<number> => {
|
|
187
|
+
// https://systeminformation.io/
|
|
188
|
+
const valueObject = {
|
|
189
|
+
cpu: '*'
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const sysinfo = await si.get(valueObject);
|
|
193
|
+
let numCPUs = 2;
|
|
194
|
+
if (goptions.useCPUs > 0) {
|
|
195
|
+
if (goptions.useCPUs >= 1) {
|
|
196
|
+
numCPUs = goptions.useCPUs;
|
|
197
|
+
} else {
|
|
198
|
+
numCPUs = Math.round(sysinfo.cpu.cores * goptions.useCPUs);
|
|
199
|
+
}
|
|
200
|
+
} else {
|
|
201
|
+
numCPUs = sysinfo.cpu.physicalCores;
|
|
202
|
+
}
|
|
203
|
+
return numCPUs;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const LogInfoMessage = (message: string) => {
|
|
207
|
+
console.log(message);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const LogSystemTelemetry = async () => {
|
|
211
|
+
// https://systeminformation.io/
|
|
212
|
+
const valueObject = {
|
|
213
|
+
system: '*',
|
|
214
|
+
osInfo: '*',
|
|
215
|
+
cpu: '*',
|
|
216
|
+
mem: '*',
|
|
217
|
+
dockerInfo: '*',
|
|
218
|
+
//dockerImages: '*',
|
|
219
|
+
dockerContainers: '*',
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const sysinfo = await si.get(valueObject);
|
|
223
|
+
const numCPUs = await GetNumCPUs();
|
|
224
|
+
const hostname = sysinfo.osInfo.hostname;
|
|
225
|
+
|
|
226
|
+
const hostaddr = GetFirstNetworkInterface();
|
|
227
|
+
if (hostaddr !== null) {
|
|
228
|
+
LogInfoMessage(`Host Address: ${hostaddr}`);
|
|
229
|
+
} else {
|
|
230
|
+
LogInfoMessage(`Unknown Host Address.`);
|
|
231
|
+
}
|
|
232
|
+
LogInfoMessage(`Server starting with ${numCPUs} Cores/Threads`);
|
|
233
|
+
|
|
234
|
+
LogInfoMessage(`Hostname: ${hostname}`);
|
|
235
|
+
LogInfoMessage(`System: ${JSON.stringify(sysinfo.system)}`);
|
|
236
|
+
LogInfoMessage(`OS Info: ${JSON.stringify(sysinfo.osInfo)}`);
|
|
237
|
+
LogInfoMessage(`CPU: ${JSON.stringify(sysinfo.cpu)}`);
|
|
238
|
+
LogInfoMessage(`Memory: ${JSON.stringify(sysinfo.mem)}`);
|
|
239
|
+
|
|
240
|
+
const promArray: Promise<any>[] = [ ];
|
|
241
|
+
|
|
242
|
+
sysinfo.dockerContainers.forEach((dc: { id: string; }) => {
|
|
243
|
+
LogInfoMessage(dc.id);
|
|
244
|
+
const dcs = promArray.push(si.dockerContainerStats(dc.id));
|
|
245
|
+
console.log(dcs);
|
|
246
|
+
});
|
|
247
|
+
const dockerContainerStats = await Promise.all(promArray);
|
|
248
|
+
|
|
249
|
+
const sysInfo = {
|
|
250
|
+
hostname,
|
|
251
|
+
numCPUs,
|
|
252
|
+
hostaddr,
|
|
253
|
+
system: sysinfo.system,
|
|
254
|
+
osInfo: sysinfo.osInfo,
|
|
255
|
+
cpu: sysinfo.cpu,
|
|
256
|
+
mem: sysinfo.mem,
|
|
257
|
+
dockerInfo: sysinfo.dockerInfo,
|
|
258
|
+
//dockerImages: sysinfo.dockerImages,
|
|
259
|
+
dockerContainers: sysinfo.dockerContainers,
|
|
260
|
+
dockerContainerStats
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
console.log(sysInfo);
|
|
264
|
+
|
|
265
|
+
console.log(JSON.stringify(sysInfo));
|
|
266
|
+
}
|
|
267
|
+
|
|
183
268
|
if (cluster.isPrimary) {
|
|
184
269
|
new MasterProcessBase(ServiceConfigOptions(true, cluster.isPrimary)).SetupServer();
|
|
185
270
|
//StartTestPrimary();
|
|
186
271
|
|
|
272
|
+
LogSystemTelemetry();
|
|
273
|
+
|
|
187
274
|
setTimeout(() => {
|
|
188
275
|
const p: Record<string, IPCMessageHandler> = { };
|
|
189
276
|
/*
|
|
@@ -206,7 +293,76 @@ if (cluster.isPrimary) {
|
|
|
206
293
|
}
|
|
207
294
|
*/
|
|
208
295
|
|
|
296
|
+
/*
|
|
297
|
+
const stsServiceControl: RedisMessageHandler = new RedisMessageHandler({
|
|
298
|
+
logger: defaultLogger,
|
|
299
|
+
role: 'SERVER',
|
|
300
|
+
redisUrl: goptions.imRedisMessageProcessorUrl,
|
|
301
|
+
namespace: 'stsServiceControl',
|
|
302
|
+
groups: [ ]
|
|
303
|
+
});
|
|
304
|
+
stsServiceControl.Start();
|
|
305
|
+
|
|
306
|
+
stsServiceControl.on('ping_ex', (pingData: JSONObject, callback: any) => {
|
|
307
|
+
console.log(chalk.yellow(`${process.pid}: stsServiceControl.on(ping): [${JSON.stringify(pingData)}]`));
|
|
308
|
+
callback({pingData, dateTime: new Date().getTime()})
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
setInterval(() => {
|
|
312
|
+
stsServiceControl.emit('GET_SYSTEM_TELEMETRY', { }, (response: any) => {
|
|
313
|
+
console.log(chalk.green(` ==>> ${process.pid}: Response(GET_SYSTEM_TELEMETRY): [${JSON.stringify(response)}]`));
|
|
314
|
+
});
|
|
315
|
+
}, 5000);
|
|
316
|
+
*/
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
const r1: RedisMessageHandler = new RedisMessageHandler({
|
|
321
|
+
logger: defaultLogger,
|
|
322
|
+
role: 'SERVER',
|
|
323
|
+
redisUrl: goptions.imRedisMessageProcessorUrl,
|
|
324
|
+
namespace: 'mytestapp',
|
|
325
|
+
groups: [ ]
|
|
326
|
+
});
|
|
327
|
+
r1.Start();
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
let i = 0;
|
|
332
|
+
let group = '';
|
|
333
|
+
const xxx = () => {
|
|
334
|
+
setTimeout(() => {
|
|
335
|
+
|
|
336
|
+
i++;
|
|
337
|
+
|
|
338
|
+
if (i % 2 === 0) {
|
|
339
|
+
group = 'even'
|
|
340
|
+
} else {
|
|
341
|
+
group = 'odd'
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const emitobj = { group, i: i, a: 'a', b: 'b' };
|
|
345
|
+
r1.emit('fromprimaryredis', emitobj, (response: any) => {
|
|
346
|
+
console.log(chalk.cyan(`${process.pid}: Response(fromprimaryredis): [${JSON.stringify(response)}]`));
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
/*
|
|
350
|
+
const globalemitobj = { i: i, a: 'a', b: 'b' };
|
|
351
|
+
r1.emit('globalmessage', globalemitobj, (response: any) => {
|
|
352
|
+
console.log(chalk.cyan(`${process.pid}: Response(globalmessage): [${JSON.stringify(response)}]`));
|
|
353
|
+
});
|
|
354
|
+
*/
|
|
355
|
+
|
|
356
|
+
//xxx();
|
|
357
|
+
}, 2000);
|
|
358
|
+
}
|
|
359
|
+
xxx();
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
|
|
209
364
|
|
|
365
|
+
/*
|
|
210
366
|
const r1: RedisMessageHandler = new RedisMessageHandler({
|
|
211
367
|
logger: defaultLogger,
|
|
212
368
|
role: 'SERVER',
|
|
@@ -224,16 +380,6 @@ if (cluster.isPrimary) {
|
|
|
224
380
|
|
|
225
381
|
setTimeout(async () => {
|
|
226
382
|
for (let i=0; i < iterations; i++) {
|
|
227
|
-
/*
|
|
228
|
-
Object.keys(p).forEach(async (pKey) => {
|
|
229
|
-
const emitobj = { i: i, a: 'a', b: 'b', worker: pKey };
|
|
230
|
-
console.log(chalk.green(`${process.pid}: emit event to worker: [${pKey}] fromprimary: [${JSON.stringify(emitobj)}`));
|
|
231
|
-
p[pKey].emit('fromprimary', emitobj, (response: any) => {
|
|
232
|
-
console.log(chalk.green(`${process.pid}: ${JSON.stringify(response)}`));
|
|
233
|
-
});
|
|
234
|
-
});
|
|
235
|
-
*/
|
|
236
|
-
|
|
237
383
|
|
|
238
384
|
const emitobj = { i: i, a: 'a', b: 'b' };
|
|
239
385
|
console.log(chalk.cyan(`${process.pid}: emit event fromprimaryredis fromprimary: [${JSON.stringify(emitobj)}`));
|
|
@@ -245,12 +391,45 @@ if (cluster.isPrimary) {
|
|
|
245
391
|
}
|
|
246
392
|
|
|
247
393
|
}, 1000);
|
|
394
|
+
*/
|
|
248
395
|
}, 1000);
|
|
249
396
|
} else {
|
|
250
397
|
new WorkerProcess(ServiceConfigOptions(true, cluster.isPrimary)).SetupServer();
|
|
251
398
|
//StartTestWorker();
|
|
252
399
|
|
|
253
400
|
setTimeout(async () => {
|
|
401
|
+
|
|
402
|
+
let group = '';
|
|
403
|
+
if (process.pid % 2 === 0) {
|
|
404
|
+
group = 'even'
|
|
405
|
+
} else {
|
|
406
|
+
group = 'odd'
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const r1: RedisMessageHandler = new RedisMessageHandler({
|
|
410
|
+
logger: defaultLogger,
|
|
411
|
+
role: 'CLIENT',
|
|
412
|
+
redisUrl: goptions.imRedisMessageProcessorUrl,
|
|
413
|
+
namespace: 'mytestapp',
|
|
414
|
+
groups: [ group ]
|
|
415
|
+
});
|
|
416
|
+
r1.Start();
|
|
417
|
+
|
|
418
|
+
r1.on('fromprimaryredis', (arg1: JSONObject, callback: any) => {
|
|
419
|
+
console.log(chalk.greenBright(` -->> ${process.pid}: fromprimaryredis.ON: [${JSON.stringify(arg1)}]`));
|
|
420
|
+
callback( {
|
|
421
|
+
status: `PID: [${process.pid}]: response message from event = fromprimaryredis with args ${JSON.stringify(arg1)}`
|
|
422
|
+
})
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
r1.on('globalmessage', (arg1: JSONObject, callback: any) => {
|
|
426
|
+
console.log(chalk.greenBright(` -->> ${process.pid}: globalmessage.ON: [${JSON.stringify(arg1)}]`));
|
|
427
|
+
callback( {
|
|
428
|
+
status: `PID: [${process.pid}]: response message from event = globalmessage with args ${JSON.stringify(arg1)}`
|
|
429
|
+
})
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
|
|
254
433
|
/*
|
|
255
434
|
const w1: IPCMessageHandler = new IPCMessageHandler({
|
|
256
435
|
logger: defaultLogger,
|
|
@@ -265,6 +444,7 @@ if (cluster.isPrimary) {
|
|
|
265
444
|
});
|
|
266
445
|
*/
|
|
267
446
|
|
|
447
|
+
/*
|
|
268
448
|
const r1: RedisMessageHandler = new RedisMessageHandler({
|
|
269
449
|
logger: defaultLogger,
|
|
270
450
|
role: 'CLIENT',
|
|
@@ -282,12 +462,6 @@ if (cluster.isPrimary) {
|
|
|
282
462
|
setTimeout(async () => {
|
|
283
463
|
for (let i=0; i < iterations; i++) {
|
|
284
464
|
const id = uuidv4();
|
|
285
|
-
/*
|
|
286
|
-
console.log(chalk.yellow(`${process.pid}: emit event fromworker: [${id} ${i} Hello]`));
|
|
287
|
-
w1.emit('fromworker', id, i, 'Hello', (response: any) => {
|
|
288
|
-
console.log(chalk.yellow(`${process.pid}: ${JSON.stringify(response)}`));
|
|
289
|
-
});
|
|
290
|
-
*/
|
|
291
465
|
|
|
292
466
|
console.log(chalk.green(`${process.pid}: emit event fromworkerredis: [${id} ${i} Hello]`));
|
|
293
467
|
r1.emit('fromworkerredis', id, i, 'Hello', (response: any) => {
|
|
@@ -296,5 +470,6 @@ if (cluster.isPrimary) {
|
|
|
296
470
|
await Sleep(delay);
|
|
297
471
|
}
|
|
298
472
|
}, 1000);
|
|
473
|
+
*/
|
|
299
474
|
}, 1000);
|
|
300
475
|
}
|
package/src/workerprocessbase.ts
CHANGED
|
@@ -12,6 +12,13 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
12
12
|
|
|
13
13
|
import { STSTransportLoggerWinston } from './stsTransportLoggerWinston'
|
|
14
14
|
|
|
15
|
+
import { RedisMessageHandler } from './redisMessageHandler';
|
|
16
|
+
|
|
17
|
+
import { goptions } from '@nsshunt/stsconfig'
|
|
18
|
+
|
|
19
|
+
import si from 'systeminformation' // https://systeminformation.io/
|
|
20
|
+
import { GetFirstNetworkInterface } from './network'
|
|
21
|
+
|
|
15
22
|
/**
|
|
16
23
|
* todo
|
|
17
24
|
* @typedef {Object} options - todo
|
|
@@ -21,6 +28,10 @@ export class WorkerProcessBase extends ServerProcessBase implements IWorkerProce
|
|
|
21
28
|
{
|
|
22
29
|
#inFlightMessage: IPCMessages = { }
|
|
23
30
|
#requestResponseMessageTimeout = 2000; //@@ config
|
|
31
|
+
#redisMessageHandler: RedisMessageHandler | null = null;
|
|
32
|
+
#redisMessageHandlerPing: number = 1000;
|
|
33
|
+
#pingTimeout: NodeJS.Timeout | null = null;
|
|
34
|
+
#instanceId: string = uuidv4();
|
|
24
35
|
|
|
25
36
|
constructor(options: ProcessOptions) {
|
|
26
37
|
super(options);
|
|
@@ -120,14 +131,77 @@ export class WorkerProcessBase extends ServerProcessBase implements IWorkerProce
|
|
|
120
131
|
return parentResponse;
|
|
121
132
|
}
|
|
122
133
|
|
|
123
|
-
SetupServer = async () =>
|
|
124
|
-
{
|
|
134
|
+
SetupServer = async () => {
|
|
125
135
|
this.SetupInstrumentation();
|
|
126
136
|
setTimeout(() => {
|
|
127
137
|
this.SetupServerEx();
|
|
128
138
|
}, 100);
|
|
129
139
|
}
|
|
130
140
|
|
|
141
|
+
GetNumCPUs = async (): Promise<number> => {
|
|
142
|
+
// https://systeminformation.io/
|
|
143
|
+
const valueObject = {
|
|
144
|
+
cpu: '*'
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const sysinfo = await si.get(valueObject);
|
|
148
|
+
let numCPUs = 2;
|
|
149
|
+
if (goptions.useCPUs > 0) {
|
|
150
|
+
if (goptions.useCPUs >= 1) {
|
|
151
|
+
numCPUs = goptions.useCPUs;
|
|
152
|
+
} else {
|
|
153
|
+
numCPUs = Math.round(sysinfo.cpu.cores * goptions.useCPUs);
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
numCPUs = sysinfo.cpu.physicalCores;
|
|
157
|
+
}
|
|
158
|
+
return numCPUs;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
GetSystemTelemetry = async () => {
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
// https://systeminformation.io/
|
|
165
|
+
const valueObject = {
|
|
166
|
+
system: '*',
|
|
167
|
+
osInfo: '*',
|
|
168
|
+
cpu: '*',
|
|
169
|
+
mem: '*',
|
|
170
|
+
dockerInfo: '*',
|
|
171
|
+
//dockerImages: '*',
|
|
172
|
+
dockerContainers: '*',
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const sysinfo = await si.get(valueObject);
|
|
176
|
+
const numCPUs = await this.GetNumCPUs();
|
|
177
|
+
const hostname = sysinfo.osInfo.hostname;
|
|
178
|
+
const hostaddr = GetFirstNetworkInterface();
|
|
179
|
+
|
|
180
|
+
const promArray: Promise<any>[] = [ ];
|
|
181
|
+
|
|
182
|
+
sysinfo.dockerContainers.forEach((dc: { id: string; }) => {
|
|
183
|
+
const dcs = promArray.push(si.dockerContainerStats(dc.id));
|
|
184
|
+
console.log(dcs);
|
|
185
|
+
});
|
|
186
|
+
const dockerContainerStats = await Promise.all(promArray);
|
|
187
|
+
|
|
188
|
+
const sysInfo = {
|
|
189
|
+
instanceId: this.#instanceId,
|
|
190
|
+
hostname,
|
|
191
|
+
numCPUs,
|
|
192
|
+
hostaddr,
|
|
193
|
+
system: sysinfo.system,
|
|
194
|
+
osInfo: sysinfo.osInfo,
|
|
195
|
+
cpu: sysinfo.cpu,
|
|
196
|
+
mem: sysinfo.mem,
|
|
197
|
+
dockerInfo: sysinfo.dockerInfo,
|
|
198
|
+
dockerContainers: sysinfo.dockerContainers,
|
|
199
|
+
dockerContainerStats
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return sysInfo;
|
|
203
|
+
}
|
|
204
|
+
|
|
131
205
|
SetupServerEx = async () => {
|
|
132
206
|
this.ProcessStartup();
|
|
133
207
|
|
|
@@ -192,8 +266,55 @@ export class WorkerProcessBase extends ServerProcessBase implements IWorkerProce
|
|
|
192
266
|
|
|
193
267
|
await this.SetupSTSServer();
|
|
194
268
|
|
|
269
|
+
/*
|
|
270
|
+
this.#redisMessageHandler = new RedisMessageHandler({
|
|
271
|
+
logger: this.options.logger,
|
|
272
|
+
role: 'CLIENT',
|
|
273
|
+
redisUrl: goptions.imRedisMessageProcessorUrl,
|
|
274
|
+
namespace: 'stsServiceControl',
|
|
275
|
+
groups: [ ]
|
|
276
|
+
});
|
|
277
|
+
this.#redisMessageHandler.Start();
|
|
278
|
+
|
|
279
|
+
const ping = () => {
|
|
280
|
+
this.#pingTimeout = setTimeout(() => {
|
|
281
|
+
const pingData = {
|
|
282
|
+
instanceId: this.#instanceId
|
|
283
|
+
}
|
|
284
|
+
if (this.#redisMessageHandler) {
|
|
285
|
+
this.#redisMessageHandler.emit('ping_ex', pingData, (response: any) => {
|
|
286
|
+
console.log(chalk.cyan(` ==>> ${process.pid}: Response(ping): [${JSON.stringify(response)}]`));
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
ping();
|
|
290
|
+
}, this.#redisMessageHandlerPing).unref();
|
|
291
|
+
}
|
|
292
|
+
ping();
|
|
293
|
+
*/
|
|
294
|
+
|
|
295
|
+
// this.#redisMessageHandler.on('GET_SYSTEM_TELEMETRY', async (getSystemTelemetryCommand: JSONObject, callback: any) => {
|
|
296
|
+
// callback({ instanceId: this.#instanceId, process: process.pid, systemTelemetry: getSystemTelemetryCommand });
|
|
297
|
+
/*
|
|
298
|
+
if (getSystemTelemetryCommand.instanceId.localeCompare(this.#instanceId) === 0) {
|
|
299
|
+
const systemTelemetry = await this.GetSystemTelemetry();
|
|
300
|
+
callback({ systemTelemetry });
|
|
301
|
+
} else {
|
|
302
|
+
callback({ systemTelemetry: null });
|
|
303
|
+
}
|
|
304
|
+
*/
|
|
305
|
+
// });
|
|
306
|
+
|
|
195
307
|
this.WorkerStarted();
|
|
196
308
|
|
|
197
309
|
this.LogInfoMessage(chalk.green(`Worker process:${process.pid} started`));
|
|
198
310
|
};
|
|
311
|
+
|
|
312
|
+
override ProcessTerminate(): Promise<void> {
|
|
313
|
+
//this.#redisMessageHandler?.off()
|
|
314
|
+
if (this.#pingTimeout) {
|
|
315
|
+
clearTimeout(this.#pingTimeout);
|
|
316
|
+
}
|
|
317
|
+
this.#redisMessageHandler?.Stop();
|
|
318
|
+
return super.ProcessTerminate();
|
|
319
|
+
}
|
|
199
320
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipcMessageHandler.d.ts","sourceRoot":"","sources":["../src/ipcMessageHandler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAgB,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAiB,MAAM,mBAAmB,CAAA;AAMzE,MAAM,WAAW,wBAAwB;IACrC,MAAM,EAAE,UAAU,CAAA;IAClB,6BAA6B,EAAE,MAAM,CAAA;IACrC,SAAS,EAAE,MAAM,CAAA;CAEpB;AAED,qBAAa,iBAAkB,SAAQ,WAAW;;gBAMlC,OAAO,EAAE,wBAAwB;IAU7C,IAAI,QAAQ,eAEX;IAED,YAAY,
|
|
1
|
+
{"version":3,"file":"ipcMessageHandler.d.ts","sourceRoot":"","sources":["../src/ipcMessageHandler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAgB,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAiB,MAAM,mBAAmB,CAAA;AAMzE,MAAM,WAAW,wBAAwB;IACrC,MAAM,EAAE,UAAU,CAAA;IAClB,6BAA6B,EAAE,MAAM,CAAA;IACrC,SAAS,EAAE,MAAM,CAAA;CAEpB;AAED,qBAAa,iBAAkB,SAAQ,WAAW;;gBAMlC,OAAO,EAAE,wBAAwB;IAU7C,IAAI,QAAQ,eAEX;IAED,YAAY,aAwBX;IAED,WAAW,aAwBV;IAED,WAAW,YAAmB,UAAU,KAAG,OAAO,CAAC,UAAU,CAAC,CAW7D;IAwBQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI;IAejD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI;IAQjD,KAAK,YAAa,MAAM,UAOvB;IAED,IAAI,aAOH;IAED,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,CAE1B;IAEQ,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;CAcrD"}
|