@nsshunt/stsmessaging 1.0.55 → 1.0.57

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.
@@ -1,838 +0,0 @@
1
- import { v4 } from "uuid";
2
- import { TinyEmitter } from "tiny-emitter";
3
- import { Redis } from "ioredis";
4
- import chalk from "chalk";
5
- import { defaultLogger } from "@nsshunt/stsutils";
6
- class MessagingManager {
7
- #id;
8
- #options;
9
- #inflightMessages = {};
10
- #messageHeader;
11
- constructor(options) {
12
- this.#id = v4();
13
- this.#options = options;
14
- this.#messageHeader = `__STS__${this.#options.namespace}__${v4()}`;
15
- }
16
- get id() {
17
- return this.#id;
18
- }
19
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
20
- ReceivedMessageFromMaster(msg) {
21
- }
22
- SendMessageNoResponse = (payload, options) => {
23
- this.#SendMessageNoResponse(payload, options);
24
- };
25
- SendMessage = (payload, options) => {
26
- return new Promise((resolve, reject) => {
27
- this.#SendMessage(
28
- payload,
29
- options,
30
- (payload2) => {
31
- resolve(payload2.responsePayload);
32
- },
33
- (payload2) => {
34
- reject(payload2.requestPayload);
35
- }
36
- );
37
- });
38
- };
39
- #SendMessageNoResponse = (payload, options) => {
40
- const messageId = v4();
41
- const requestPayload = {
42
- header: this.#messageHeader,
43
- messageId,
44
- senderId: this.#id,
45
- senderRole: this.#options.role,
46
- requestPayload: payload,
47
- responsePayload: {},
48
- pid: process.pid.toString(),
49
- messageType: "REQUEST_NO_RESPONSE"
50
- };
51
- this.#options.messageSender(requestPayload, options);
52
- };
53
- #SendMessage = (payload, options, callBack, errorCallBack) => {
54
- const messageId = v4();
55
- const requestPayload = {
56
- header: this.#messageHeader,
57
- messageId,
58
- senderId: this.#id,
59
- senderRole: this.#options.role,
60
- requestPayload: payload,
61
- responsePayload: {},
62
- pid: process.pid.toString(),
63
- messageType: "REQUEST"
64
- };
65
- const messageRecord = {
66
- messageId,
67
- senderId: this.#id,
68
- senderRole: this.#options.role,
69
- requestPayload,
70
- responses: {},
71
- // record
72
- startTime: performance.now(),
73
- endTime: 0,
74
- timeout: setTimeout(() => {
75
- setTimeout(() => {
76
- delete this.#inflightMessages[messageRecord.messageId];
77
- }, 0).unref();
78
- errorCallBack(requestPayload);
79
- }, this.#options.requestResponseMessageTimeout).unref(),
80
- // max message timeout allowed
81
- callBack,
82
- errorCallBack
83
- };
84
- this.#inflightMessages[messageRecord.messageId] = messageRecord;
85
- this.#options.messageSender(requestPayload, options);
86
- };
87
- #ProcessMessage = async (msg, options) => {
88
- if (msg.header && msg.header.localeCompare(this.#messageHeader) === 0) {
89
- const message = msg;
90
- if (this.#inflightMessages[message.messageId]) {
91
- const inFlightMessageRecord = this.#inflightMessages[message.messageId];
92
- inFlightMessageRecord.responses[message.senderId] = { ...message };
93
- let completed = true;
94
- if (this.#options.ProcessResponseMessage) {
95
- completed = await this.#options.ProcessResponseMessage(inFlightMessageRecord.responses, options);
96
- if (completed) {
97
- inFlightMessageRecord.endTime = performance.now();
98
- clearTimeout(inFlightMessageRecord.timeout);
99
- inFlightMessageRecord.callBack({
100
- responsePayload: Object.values(inFlightMessageRecord.responses).map((r) => r.responsePayload)
101
- }, options);
102
- delete this.#inflightMessages[message.messageId];
103
- }
104
- } else if (completed) {
105
- inFlightMessageRecord.endTime = performance.now();
106
- clearTimeout(inFlightMessageRecord.timeout);
107
- inFlightMessageRecord.callBack(message, options);
108
- delete this.#inflightMessages[message.messageId];
109
- } else ;
110
- }
111
- }
112
- };
113
- Start = (options) => {
114
- this.#messageHeader = `__STS__${this.#options.namespace}__${v4()}`;
115
- this.#options.messageReceiverStart(options);
116
- };
117
- Stop = (options) => {
118
- this.#options.messageReceiverStop(options);
119
- for (const [, iPCMessageProcessorWorkerRecord] of Object.entries(this.#inflightMessages)) {
120
- if (iPCMessageProcessorWorkerRecord.timeout) {
121
- clearTimeout(iPCMessageProcessorWorkerRecord.timeout);
122
- }
123
- }
124
- this.#inflightMessages = {};
125
- };
126
- // Process a message recieved from a worker
127
- ProcessMessage = async (msg, options) => {
128
- if (msg.header) {
129
- const checkName = `__STS__${this.#options.namespace}__`;
130
- if (msg.header.includes(checkName)) {
131
- const message = msg;
132
- if (msg.messageType.localeCompare("REQUEST") === 0 || msg.messageType.localeCompare("REQUEST_NO_RESPONSE") === 0) {
133
- let processMessage = true;
134
- if (message.requestPayload.args && message.requestPayload.args.length > 0 && message.requestPayload.args[0].group) {
135
- const group = message.requestPayload.args[0].group;
136
- processMessage = this.#options.groups.indexOf(group) === -1 ? false : true;
137
- }
138
- if (processMessage) {
139
- if (msg.messageType.localeCompare("REQUEST_NO_RESPONSE") === 0) {
140
- this.#options.ProcessRequestMessage(message, options);
141
- } else {
142
- message.responsePayload = await this.#options.ProcessRequestMessage(message, options);
143
- message.senderId = this.#id;
144
- message.messageType = "RESPONSE";
145
- this.#options.messageSender(message, options);
146
- }
147
- }
148
- } else {
149
- this.#ProcessMessage(msg, options);
150
- }
151
- }
152
- }
153
- };
154
- }
155
- const REQUEST_CHANNEL = "__STS__SVC_stsappframework_request";
156
- const RESPONSE_CHANNEL = "__STS__SVC_stsappframework_response";
157
- class RedisMessageHandler extends TinyEmitter {
158
- #messagingManager = null;
159
- #options;
160
- #events = {};
161
- #requestChannel;
162
- #responseChannel;
163
- #ioredisSubscriber;
164
- #ioredisPublisher;
165
- #clients = {};
166
- #pingTimeout = null;
167
- constructor(options) {
168
- super();
169
- this.#options = options;
170
- this.#requestChannel = REQUEST_CHANNEL;
171
- this.#responseChannel = RESPONSE_CHANNEL;
172
- const redisOptions = {
173
- showFriendlyErrorStack: true,
174
- maxRetriesPerRequest: 20
175
- };
176
- this.#ioredisSubscriber = new Redis(this.#options.redisUrl, redisOptions);
177
- this.#ioredisPublisher = new Redis(this.#options.redisUrl, redisOptions);
178
- this.#ioredisSubscriber.on("error", (error) => {
179
- this.#LogError(chalk.red(`RedisMessageHandler:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Error (redisSubscriber on error): [${error}]`));
180
- });
181
- this.#ioredisPublisher.on("error", (error) => {
182
- this.#LogError(chalk.red(`RedisMessageHandler:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Error (redisPublisher on error): [${error}]`));
183
- });
184
- this.#ioredisSubscriber.subscribe(this.#requestChannel, this.#responseChannel, (error, count) => {
185
- if (error) {
186
- this.#LogError(chalk.red(`RedisMessageHandler:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Error - Failed to subscribe: [${error}]`));
187
- } else {
188
- this.#LogInfo(chalk.white(`RedisMessageHandler:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Subscribed successfully! This client is currently subscribed to ${count} channels.`));
189
- }
190
- });
191
- this.SetupPrimary();
192
- if (this.#options.role.localeCompare("CLIENT") === 0) {
193
- const ping = () => {
194
- this.#pingTimeout = setTimeout(() => {
195
- const pingData = {
196
- id: this.#messagingManager.id,
197
- groups: this.#options.groups
198
- };
199
- if (this.#options.extraData) {
200
- pingData.extraData = this.#options.extraData;
201
- }
202
- this.emitNoResponse("ping", pingData);
203
- ping();
204
- }, 1e3).unref();
205
- };
206
- ping();
207
- } else {
208
- this.on("ping", (pingData, callback) => {
209
- const { id, groups, extraData } = pingData;
210
- if (this.#clients[id]) {
211
- clearTimeout(this.#clients[id].timeout);
212
- this.#clients[id].pingCount++;
213
- this.#clients[id].timeout = setTimeout(() => {
214
- delete this.#clients[id];
215
- }, 2e3);
216
- this.#clients[id].groups = groups;
217
- this.#clients[id].extraData = extraData;
218
- } else {
219
- this.#clients[id] = {
220
- id,
221
- clientConnected: /* @__PURE__ */ new Date(),
222
- pingCount: 0,
223
- timeout: setTimeout(() => {
224
- delete this.#clients[id];
225
- }, 2e3),
226
- groups,
227
- extraData
228
- };
229
- }
230
- });
231
- }
232
- }
233
- #LogInfo(message) {
234
- this.#options.logger.info(message);
235
- }
236
- #LogError(message) {
237
- this.#options.logger.error(message);
238
- }
239
- #processRawMessage = (channel, rawmessage) => {
240
- const message = JSON.parse(rawmessage);
241
- this.#messagingManager?.ProcessMessage(message, { channel });
242
- };
243
- get clients() {
244
- return this.#clients;
245
- }
246
- get groups() {
247
- return this.#options.groups;
248
- }
249
- AddGroup = (group) => {
250
- const index = this.#options.groups.indexOf(group);
251
- if (index === -1) {
252
- this.#options.groups.push(group);
253
- }
254
- };
255
- RemoveGroup = (group) => {
256
- const removeIndex = this.#options.groups.indexOf(group);
257
- if (removeIndex !== -1) {
258
- this.#options.groups.splice(removeIndex, 1);
259
- }
260
- };
261
- SetupPrimary = () => {
262
- const ipcMessageManagerOptions = {
263
- logger: this.#options.logger,
264
- requestResponseMessageTimeout: 5e3,
265
- namespace: this.#options.namespace,
266
- role: this.#options.role,
267
- groups: this.#options.groups,
268
- messageSender: this.#messageSender,
269
- // This method is used to calculate if all responses have been received from multiple clients (broadcast)
270
- // returns true/false.
271
- ProcessResponseMessage: this.#ProcessResponseMessage,
272
- // This gets called when an event is received from a message receiver (when ProcessMessage is invoked from the receiver event handler)
273
- ProcessRequestMessage: this.#processPayload,
274
- messageReceiverStart: (options) => {
275
- this.#ioredisSubscriber.on("message", this.#processRawMessage);
276
- },
277
- messageReceiverStop: (options) => {
278
- this.#ioredisSubscriber.off("message", this.#processRawMessage);
279
- }
280
- };
281
- this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
282
- };
283
- #messageSender = (payload, options) => {
284
- if (payload.messageType.localeCompare("REQUEST") === 0 || payload.messageType.localeCompare("REQUEST_NO_RESPONSE") === 0) {
285
- this.#ioredisPublisher.publish(this.#requestChannel, JSON.stringify(payload));
286
- } else if (payload.messageType.localeCompare("RESPONSE") === 0) {
287
- this.#ioredisPublisher.publish(this.#responseChannel, JSON.stringify(payload));
288
- }
289
- };
290
- #ProcessResponseMessage = async (responses, options) => {
291
- let found = true;
292
- let requestGroup = null;
293
- for (const [responseId, response] of Object.entries(responses)) {
294
- if (response.requestPayload.args.length > 0 && response.requestPayload.args[0].group) {
295
- requestGroup = response.requestPayload.args[0].group;
296
- break;
297
- }
298
- }
299
- if (requestGroup) {
300
- const clientsInGroup = Object.values(this.#clients).filter((c) => {
301
- if (c.groups.indexOf(requestGroup) === -1) {
302
- return false;
303
- }
304
- return true;
305
- });
306
- found = true;
307
- clientsInGroup.forEach((c) => {
308
- if (!responses[c.id]) {
309
- found = false;
310
- }
311
- });
312
- } else {
313
- const clientsInGroup = Object.values(this.#clients);
314
- found = true;
315
- clientsInGroup.forEach((c) => {
316
- if (!responses[c.id]) {
317
- found = false;
318
- }
319
- });
320
- }
321
- return found;
322
- };
323
- #processPayload = (payload, options) => {
324
- return new Promise((resolve, reject) => {
325
- if (payload.messageType.localeCompare("REQUEST") === 0 || payload.messageType.localeCompare("REQUEST_NO_RESPONSE") === 0) {
326
- if (payload.requestPayload["__eventName"]) {
327
- const eventName = payload.requestPayload["__eventName"];
328
- if (this.#events[eventName]) {
329
- try {
330
- if (payload.messageType.localeCompare("REQUEST_NO_RESPONSE") === 0) {
331
- this.#events[eventName].callback(...payload.requestPayload.args);
332
- resolve({});
333
- } else {
334
- this.#events[eventName].callback(...payload.requestPayload.args, (responseMessage) => {
335
- resolve(responseMessage);
336
- });
337
- }
338
- } catch (error) {
339
- reject(error);
340
- }
341
- }
342
- }
343
- }
344
- });
345
- };
346
- // p.on('fromworker', (arg1: number, arg2: string, callback: any) => {
347
- on(event, callback, ctx) {
348
- if (this.#events[event]) {
349
- delete this.#events[event];
350
- }
351
- const eventObject = {
352
- event,
353
- callback,
354
- ctx
355
- };
356
- this.#events[eventObject.event] = eventObject;
357
- return this;
358
- }
359
- off(event, callback) {
360
- if (this.#events[event]) {
361
- delete this.#events[event];
362
- }
363
- return this;
364
- }
365
- Start = () => {
366
- this.#messagingManager?.Start();
367
- };
368
- Stop = () => {
369
- if (this.#pingTimeout) {
370
- clearTimeout(this.#pingTimeout);
371
- this.#pingTimeout = null;
372
- }
373
- this.#messagingManager?.Stop();
374
- this.#ioredisSubscriber.quit();
375
- this.#ioredisSubscriber.disconnect();
376
- this.#ioredisPublisher.quit();
377
- this.#ioredisPublisher.disconnect();
378
- };
379
- emit(event, ...args) {
380
- (async () => {
381
- try {
382
- const retVal = await this.#messagingManager?.SendMessage({
383
- __eventName: event,
384
- args: args.slice(0, args.length - 1)
385
- });
386
- args[args.length - 1](retVal);
387
- } catch (error) {
388
- if (this.#options.ignoreEvents) {
389
- if (this.#options.ignoreEvents.indexOf(error.__eventName) !== -1) {
390
- return;
391
- }
392
- }
393
- this.#options.logger.error(chalk.red(`RedisMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));
394
- }
395
- })();
396
- return this;
397
- }
398
- emitWithError(event, args, responseCb, errorCb) {
399
- (async () => {
400
- try {
401
- const retVal = await this.#messagingManager?.SendMessage({
402
- __eventName: event,
403
- args: [args]
404
- });
405
- responseCb(retVal);
406
- } catch (error) {
407
- if (this.#options.ignoreEvents) {
408
- if (this.#options.ignoreEvents.indexOf(error.__eventName) !== -1) {
409
- return;
410
- }
411
- }
412
- errorCb(error);
413
- }
414
- })();
415
- return this;
416
- }
417
- emitex = async (event, ...args) => {
418
- return this.#messagingManager.SendMessage({
419
- __eventName: event,
420
- args
421
- });
422
- };
423
- emitNoResponse = async (event, ...args) => {
424
- this.#messagingManager.SendMessageNoResponse({
425
- __eventName: event,
426
- args
427
- });
428
- };
429
- }
430
- class IPCMessageHandler extends TinyEmitter {
431
- #messagingManager = null;
432
- #options;
433
- #clients = {};
434
- #events = {};
435
- #startWorkerOptions;
436
- constructor(options) {
437
- super();
438
- this.#options = options;
439
- if (options.role.localeCompare("CLIENT") === 0) {
440
- this.SetupWorker();
441
- } else {
442
- this.SetupPrimary();
443
- }
444
- }
445
- get __events() {
446
- return this.#events;
447
- }
448
- AddClient = (client) => {
449
- const id = v4();
450
- const processMessage = (payload) => {
451
- this.#messagingManager?.ProcessMessage(payload, { client });
452
- };
453
- client.on("message", processMessage);
454
- this.#clients[id] = {
455
- client,
456
- processMessage
457
- };
458
- return id;
459
- };
460
- RemoveClient = (id) => {
461
- const clientRecord = this.#clients[id];
462
- if (clientRecord) {
463
- clientRecord.client.off("message", clientRecord.processMessage);
464
- delete this.#clients[id];
465
- }
466
- };
467
- get clients() {
468
- return this.#clients;
469
- }
470
- SetupPrimary = () => {
471
- const ipcMessageManagerOptions = {
472
- logger: defaultLogger,
473
- requestResponseMessageTimeout: 5e3,
474
- namespace: this.#options.namespace,
475
- role: "SERVER",
476
- messageSender: (payload, options) => {
477
- options.client.send(payload);
478
- },
479
- ProcessRequestMessage: async (payload, options) => {
480
- return this.#processPayload(payload, options);
481
- },
482
- //@@ also need way to add/remove a worker/child to the collection
483
- //@@ the ping should also auto remove (such as a failed worker)
484
- messageReceiverStart: (options) => {
485
- },
486
- messageReceiverStop: (options) => {
487
- },
488
- groups: []
489
- };
490
- this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
491
- };
492
- #ProcessWorkerMessageRaw = (payload) => {
493
- this.#messagingManager?.ProcessMessage(payload, this.#startWorkerOptions);
494
- };
495
- SetupWorker = () => {
496
- const ipcMessageManagerOptions = {
497
- logger: defaultLogger,
498
- requestResponseMessageTimeout: this.#options.requestResponseMessageTimeout,
499
- namespace: this.#options.namespace,
500
- role: "CLIENT",
501
- messageSender: (payload, options) => {
502
- process.send(payload);
503
- },
504
- ProcessRequestMessage: async (payload, options) => {
505
- return this.#processPayload(payload, options);
506
- },
507
- messageReceiverStart: (options) => {
508
- this.#startWorkerOptions = { ...options };
509
- process.on("message", this.#ProcessWorkerMessageRaw);
510
- },
511
- messageReceiverStop: (options) => {
512
- process.off("message", this.#ProcessWorkerMessageRaw);
513
- },
514
- groups: []
515
- };
516
- this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
517
- };
518
- SendMessage = async (payload) => {
519
- if (this.#messagingManager) {
520
- if (this.#options.role.localeCompare("CLIENT") === 0) {
521
- return this.#messagingManager?.SendMessage(payload, {});
522
- } else {
523
- const promArray = [];
524
- for (const [clientId, clientRecord] of Object.entries(this.#clients)) {
525
- promArray.push(this.#messagingManager?.SendMessage(payload, { client: clientRecord.client }));
526
- }
527
- try {
528
- const retVal = await Promise.all(promArray);
529
- return {
530
- result: retVal
531
- };
532
- } catch (error) {
533
- return {};
534
- }
535
- }
536
- } else {
537
- return {};
538
- }
539
- };
540
- #processPayload = (payload, options) => {
541
- return new Promise((resolve, reject) => {
542
- if (payload.messageType.localeCompare("REQUEST") === 0 || payload.messageType.localeCompare("REQUEST_NO_RESPONSE") === 0) {
543
- if (payload.requestPayload["__eventName"]) {
544
- const eventName = payload.requestPayload["__eventName"];
545
- if (this.#events[eventName]) {
546
- try {
547
- if (payload.messageType.localeCompare("REQUEST_NO_RESPONSE") === 0) {
548
- this.#events[eventName].callback(...payload.requestPayload.args);
549
- resolve({});
550
- } else {
551
- this.#events[eventName].callback(...payload.requestPayload.args, (responseMessage) => {
552
- resolve(responseMessage);
553
- });
554
- }
555
- } catch (error) {
556
- reject(error);
557
- }
558
- }
559
- }
560
- }
561
- });
562
- };
563
- // p.on('fromworker', (arg1: number, arg2: string, callback: any) => {
564
- on(event, callback, ctx) {
565
- if (this.#events[event]) {
566
- delete this.#events[event];
567
- }
568
- const eventObject = {
569
- event,
570
- callback,
571
- ctx
572
- };
573
- this.#events[eventObject.event] = eventObject;
574
- return this;
575
- }
576
- off(event, callback) {
577
- if (this.#events[event]) {
578
- delete this.#events[event];
579
- }
580
- return this;
581
- }
582
- // Supply complete collection of workers
583
- Start = () => {
584
- this.#messagingManager?.Start({});
585
- };
586
- // Supply complete collection of workers
587
- Stop = () => {
588
- this.#messagingManager?.Stop({});
589
- };
590
- /*
591
- override emit(event: string, ...args: any[]): this {
592
- const sendMessage = async () => {
593
- const retVal = await this.SendMessage({
594
- __eventName: event,
595
- args: args.slice(0, args.length-1)
596
- });
597
- // Invoke the response callback
598
- args[args.length-1](retVal);
599
- };
600
- sendMessage();
601
- return this;
602
- //return super.emit(event, ...args);
603
- }
604
- */
605
- emit(event, ...args) {
606
- (async () => {
607
- try {
608
- const retVal = await this.SendMessage({
609
- __eventName: event,
610
- args: args.slice(0, args.length - 1)
611
- });
612
- args[args.length - 1](retVal);
613
- } catch (error) {
614
- if (this.#options.ignoreEvents) {
615
- if (this.#options.ignoreEvents.indexOf(error.__eventName) !== -1) {
616
- return;
617
- }
618
- }
619
- console.log(error);
620
- this.#options.logger.error(chalk.red(`IPCMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));
621
- }
622
- })();
623
- return this;
624
- }
625
- emitNoResponse = async (event, ...args) => {
626
- if (this.#options.role.localeCompare("CLIENT") === 0) {
627
- this.#messagingManager.SendMessageNoResponse({
628
- __eventName: event,
629
- args
630
- });
631
- } else {
632
- for (const [clientId, clientRecord] of Object.entries(this.#clients)) {
633
- this.#messagingManager.SendMessageNoResponse({
634
- __eventName: event,
635
- args
636
- }, { client: clientRecord.client });
637
- }
638
- }
639
- };
640
- }
641
- class IPCMessageHandlerPair extends TinyEmitter {
642
- #messagingManager = null;
643
- #options;
644
- #worker = null;
645
- #events = {};
646
- #startWorkerOptions;
647
- #startPrimaryWorker = null;
648
- constructor(options) {
649
- super();
650
- this.#options = options;
651
- if (options.role.localeCompare("CLIENT") === 0) {
652
- this.SetupWorker();
653
- } else {
654
- this.SetupPrimary();
655
- }
656
- }
657
- get __events() {
658
- return this.#events;
659
- }
660
- #ProcessPrimaryMessageRaw = (payload) => {
661
- this.#messagingManager?.ProcessMessage(payload, { worker: this.#startPrimaryWorker });
662
- };
663
- SetupPrimary = () => {
664
- const ipcMessageManagerOptions = {
665
- logger: defaultLogger,
666
- requestResponseMessageTimeout: 5e3,
667
- namespace: this.#options.namespace,
668
- role: "SERVER",
669
- messageSender: (payload, options) => {
670
- options.worker.send(payload);
671
- },
672
- ProcessRequestMessage: async (payload, options) => {
673
- return this.#processPayload(payload, options);
674
- },
675
- //@@ also need way to add/remove a worker/child to the collection
676
- //@@ the ping should also auto remove (such as a failed worker)
677
- messageReceiverStart: (options) => {
678
- const worker = options.worker;
679
- this.#startPrimaryWorker = worker;
680
- worker.on("message", this.#ProcessPrimaryMessageRaw);
681
- },
682
- messageReceiverStop: (options) => {
683
- const worker = options.worker;
684
- worker.off("message", this.#ProcessPrimaryMessageRaw);
685
- },
686
- groups: []
687
- };
688
- this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
689
- };
690
- #ProcessWorkerMessageRaw = (payload) => {
691
- this.#messagingManager?.ProcessMessage(payload, this.#startWorkerOptions);
692
- };
693
- SetupWorker = () => {
694
- const ipcMessageManagerOptions = {
695
- logger: defaultLogger,
696
- requestResponseMessageTimeout: this.#options.requestResponseMessageTimeout,
697
- namespace: this.#options.namespace,
698
- role: "CLIENT",
699
- messageSender: (payload, options) => {
700
- process.send(payload);
701
- },
702
- ProcessRequestMessage: async (payload, options) => {
703
- return this.#processPayload(payload, options);
704
- },
705
- messageReceiverStart: (options) => {
706
- this.#startWorkerOptions = { ...options };
707
- process.on("message", this.#ProcessWorkerMessageRaw);
708
- },
709
- messageReceiverStop: (options) => {
710
- process.off("message", this.#ProcessWorkerMessageRaw);
711
- },
712
- groups: []
713
- };
714
- this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
715
- };
716
- SendMessage = async (payload) => {
717
- if (this.#messagingManager) {
718
- if (this.#worker) {
719
- return this.#messagingManager?.SendMessage(payload, { worker: this.#worker });
720
- } else {
721
- return this.#messagingManager?.SendMessage(payload, {});
722
- }
723
- } else {
724
- return {};
725
- }
726
- };
727
- #processPayload = (payload, options) => {
728
- return new Promise((resolve, reject) => {
729
- if (payload.messageType.localeCompare("REQUEST") === 0 || payload.messageType.localeCompare("REQUEST_NO_RESPONSE") === 0) {
730
- if (payload.requestPayload["__eventName"]) {
731
- const eventName = payload.requestPayload["__eventName"];
732
- if (this.#events[eventName]) {
733
- try {
734
- if (payload.messageType.localeCompare("REQUEST_NO_RESPONSE") === 0) {
735
- this.#events[eventName].callback(...payload.requestPayload.args);
736
- resolve({});
737
- } else {
738
- this.#events[eventName].callback(...payload.requestPayload.args, (responseMessage) => {
739
- resolve(responseMessage);
740
- });
741
- }
742
- } catch (error) {
743
- reject(error);
744
- }
745
- }
746
- }
747
- }
748
- });
749
- };
750
- // p.on('fromworker', (arg1: number, arg2: string, callback: any) => {
751
- on(event, callback, ctx) {
752
- if (this.#events[event]) {
753
- delete this.#events[event];
754
- }
755
- const eventObject = {
756
- event,
757
- callback,
758
- ctx
759
- };
760
- this.#events[eventObject.event] = eventObject;
761
- return this;
762
- }
763
- off(event, callback) {
764
- if (this.#events[event]) {
765
- delete this.#events[event];
766
- }
767
- return this;
768
- }
769
- // Supply complete collection of workers
770
- Start = (worker) => {
771
- if (worker) {
772
- this.#messagingManager?.Start({ worker });
773
- this.#worker = worker;
774
- } else {
775
- this.#messagingManager?.Start({});
776
- }
777
- };
778
- // Supply complete collection of workers
779
- Stop = () => {
780
- if (this.#worker) {
781
- this.#messagingManager?.Stop({ worker: this.#worker });
782
- this.#worker = null;
783
- } else {
784
- this.#messagingManager?.Stop({});
785
- }
786
- };
787
- get worker() {
788
- return this.#worker;
789
- }
790
- /*
791
- override emit(event: string, ...args: any[]): this {
792
- const sendMessage = async () => {
793
- const retVal = await this.SendMessage({
794
- __eventName: event,
795
- args: args.slice(0, args.length-1)
796
- });
797
- // Invoke the response callback
798
- args[args.length-1](retVal);
799
- };
800
- sendMessage();
801
- return this;
802
- //return super.emit(event, ...args);
803
- }
804
- */
805
- emit(event, ...args) {
806
- (async () => {
807
- try {
808
- const retVal = await this.SendMessage({
809
- __eventName: event,
810
- args: args.slice(0, args.length - 1)
811
- });
812
- args[args.length - 1](retVal);
813
- } catch (error) {
814
- if (this.#options.ignoreEvents) {
815
- if (this.#options.ignoreEvents.indexOf(error.__eventName) !== -1) {
816
- return;
817
- }
818
- }
819
- console.log(error);
820
- this.#options.logger.error(chalk.red(`IPCMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));
821
- }
822
- })();
823
- return this;
824
- }
825
- emitNoResponse = async (event, ...args) => {
826
- this.#messagingManager.SendMessageNoResponse({
827
- __eventName: event,
828
- args
829
- });
830
- };
831
- }
832
- export {
833
- IPCMessageHandler,
834
- IPCMessageHandlerPair,
835
- MessagingManager,
836
- RedisMessageHandler
837
- };
838
- //# sourceMappingURL=stsmessaging.mjs.map