@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.
Files changed (35) hide show
  1. package/dist/ipcMessageHandler.js +4 -2
  2. package/dist/ipcMessageHandler.js.map +1 -1
  3. package/dist/ipcMessageManager.js +32 -4
  4. package/dist/ipcMessageManager.js.map +1 -1
  5. package/dist/ipcMessageProcessorPrimary.js +2 -1
  6. package/dist/ipcMessageProcessorPrimary.js.map +1 -1
  7. package/dist/ipcMessageProcessorWorker.js +2 -1
  8. package/dist/ipcMessageProcessorWorker.js.map +1 -1
  9. package/dist/redisMessageHandler.js +144 -6
  10. package/dist/redisMessageHandler.js.map +1 -1
  11. package/dist/redisMessageHandler.test.js +4 -2
  12. package/dist/redisMessageHandler.test.js.map +1 -1
  13. package/dist/testing/app.js +191 -37
  14. package/dist/testing/app.js.map +1 -1
  15. package/dist/workerprocessbase.js +107 -0
  16. package/dist/workerprocessbase.js.map +1 -1
  17. package/package.json +1 -1
  18. package/runtest2.sh +1 -1
  19. package/src/ipcMessageHandler.ts +4 -2
  20. package/src/ipcMessageManager.ts +40 -4
  21. package/src/ipcMessageProcessorPrimary.ts +2 -1
  22. package/src/ipcMessageProcessorWorker.ts +2 -1
  23. package/src/redisMessageHandler.test.ts +4 -2
  24. package/src/redisMessageHandler.ts +155 -6
  25. package/src/testing/app.ts +192 -17
  26. package/src/workerprocessbase.ts +123 -2
  27. package/types/ipcMessageHandler.d.ts.map +1 -1
  28. package/types/ipcMessageManager.d.ts +1 -0
  29. package/types/ipcMessageManager.d.ts.map +1 -1
  30. package/types/ipcMessageProcessorPrimary.d.ts.map +1 -1
  31. package/types/ipcMessageProcessorWorker.d.ts.map +1 -1
  32. package/types/redisMessageHandler.d.ts +2 -0
  33. package/types/redisMessageHandler.d.ts.map +1 -1
  34. package/types/workerprocessbase.d.ts +15 -0
  35. 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
- this.emit('ping', this.#ipcMessageManager?.id, (response: any) => { });
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', (id: string, callback: any) => {
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 (!responses[c.id]) {
172
- found = false;
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
- if (found) {
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
 
@@ -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 = 100;
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
  }
@@ -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,aAuBX;IAED,WAAW,aAuBV;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"}
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"}