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