@nsshunt/stsappframework 3.1.209 → 3.1.211

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 (82) hide show
  1. package/build.sh +5 -0
  2. package/dist/commonTypes.js.map +1 -1
  3. package/dist/index.js +0 -5
  4. package/dist/index.js.map +1 -1
  5. package/dist/masterprocessbase.js +3 -53
  6. package/dist/masterprocessbase.js.map +1 -1
  7. package/dist/processbase.js +4 -17
  8. package/dist/processbase.js.map +1 -1
  9. package/dist/testing/app.js +0 -457
  10. package/dist/testing/app.js.map +1 -1
  11. package/dist/workerprocessbase.js +1 -36
  12. package/dist/workerprocessbase.js.map +1 -1
  13. package/package.json +14 -13
  14. package/src/commonTypes.ts +2 -33
  15. package/src/index.ts +0 -5
  16. package/src/masterprocessbase.ts +4 -18
  17. package/src/processbase.ts +7 -22
  18. package/src/testing/app.ts +1 -530
  19. package/src/workerprocessbase.ts +1 -40
  20. package/types/commonTypes.d.ts +0 -23
  21. package/types/commonTypes.d.ts.map +1 -1
  22. package/types/index.d.ts +0 -5
  23. package/types/index.d.ts.map +1 -1
  24. package/types/masterprocessbase.d.ts.map +1 -1
  25. package/types/processbase.d.ts +0 -2
  26. package/types/processbase.d.ts.map +1 -1
  27. package/types/workerprocessbase.d.ts.map +1 -1
  28. package/dist/ipcMessageHandler.js +0 -189
  29. package/dist/ipcMessageHandler.js.map +0 -1
  30. package/dist/ipcMessageManager.js +0 -146
  31. package/dist/ipcMessageManager.js.map +0 -1
  32. package/dist/ipcMessageProcessorPrimary.js +0 -65
  33. package/dist/ipcMessageProcessorPrimary.js.map +0 -1
  34. package/dist/ipcMessageProcessorWorker.js +0 -61
  35. package/dist/ipcMessageProcessorWorker.js.map +0 -1
  36. package/dist/messagehandling/webWorkerMessageHandler.js +0 -280
  37. package/dist/messagehandling/webWorkerMessageHandler.js.map +0 -1
  38. package/dist/messagehandling/webWorkerSupport.js +0 -62
  39. package/dist/messagehandling/webWorkerSupport.js.map +0 -1
  40. package/dist/redisMessageHandler.js +0 -305
  41. package/dist/redisMessageHandler.js.map +0 -1
  42. package/dist/redisMessageHandler.test.js +0 -129
  43. package/dist/redisMessageHandler.test.js.map +0 -1
  44. package/dist/testing/app_ipc_legacy.js +0 -84
  45. package/dist/testing/app_ipc_legacy.js.map +0 -1
  46. package/dist/testing/app_ipcex.js +0 -69
  47. package/dist/testing/app_ipcex.js.map +0 -1
  48. package/dist/testing/app_ww.js +0 -54
  49. package/dist/testing/app_ww.js.map +0 -1
  50. package/src/ipcMessageHandler.ts +0 -201
  51. package/src/ipcMessageManager.ts +0 -171
  52. package/src/ipcMessageProcessorPrimary.ts +0 -76
  53. package/src/ipcMessageProcessorWorker.ts +0 -70
  54. package/src/messagehandling/webWorkerMessageHandler.ts +0 -341
  55. package/src/messagehandling/webWorkerSupport.ts +0 -66
  56. package/src/redisMessageHandler.test.ts +0 -157
  57. package/src/redisMessageHandler.ts +0 -371
  58. package/src/testing/app_ipc_legacy.ts +0 -87
  59. package/src/testing/app_ipcex.ts +0 -68
  60. package/src/testing/app_ww.ts +0 -68
  61. package/types/ipcMessageHandler.d.ts +0 -30
  62. package/types/ipcMessageHandler.d.ts.map +0 -1
  63. package/types/ipcMessageManager.d.ts +0 -30
  64. package/types/ipcMessageManager.d.ts.map +0 -1
  65. package/types/ipcMessageProcessorPrimary.d.ts +0 -26
  66. package/types/ipcMessageProcessorPrimary.d.ts.map +0 -1
  67. package/types/ipcMessageProcessorWorker.d.ts +0 -25
  68. package/types/ipcMessageProcessorWorker.d.ts.map +0 -1
  69. package/types/messagehandling/webWorkerMessageHandler.d.ts +0 -52
  70. package/types/messagehandling/webWorkerMessageHandler.d.ts.map +0 -1
  71. package/types/messagehandling/webWorkerSupport.d.ts +0 -6
  72. package/types/messagehandling/webWorkerSupport.d.ts.map +0 -1
  73. package/types/redisMessageHandler.d.ts +0 -51
  74. package/types/redisMessageHandler.d.ts.map +0 -1
  75. package/types/redisMessageHandler.test.d.ts +0 -2
  76. package/types/redisMessageHandler.test.d.ts.map +0 -1
  77. package/types/testing/app_ipc_legacy.d.ts +0 -2
  78. package/types/testing/app_ipc_legacy.d.ts.map +0 -1
  79. package/types/testing/app_ipcex.d.ts +0 -2
  80. package/types/testing/app_ipcex.d.ts.map +0 -1
  81. package/types/testing/app_ww.d.ts +0 -2
  82. package/types/testing/app_ww.d.ts.map +0 -1
@@ -1,171 +0,0 @@
1
- /* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF
2
- import { ISTSLogger, JSONObject } from '@nsshunt/stsutils'
3
-
4
- import { v4 as uuidv4 } from 'uuid';
5
-
6
- import { IIPCMessageProcessorIPCPayload, IIPCMessageProcessorWorkerRecord } from './commonTypes'
7
-
8
- export interface IPCMessageManagerOptions {
9
- logger: ISTSLogger
10
- requestResponseMessageTimeout: number
11
- namespace: string
12
- role: 'SERVER' | 'CLIENT'
13
- groups: string[]
14
- messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => void
15
- ProcessRequestMessage: (payload: IIPCMessageProcessorIPCPayload, options: any) => Promise<JSONObject>
16
- ProcessResponseMessage?: (reesponses: Record<string, IIPCMessageProcessorIPCPayload>, options: any) => Promise<boolean>
17
- messageReceiverStart: (options: any) => void
18
- messageReceiverStop: (options: any) => void
19
- }
20
- /**
21
- * todo
22
- * @typedef {Object} options - todo
23
- * @property {boolean} [wssServer=false] - Create a web socket server on this worker instance
24
- */
25
- export class IPCMessageManager
26
- {
27
- #id: string;
28
- #options: IPCMessageManagerOptions;
29
- #inflightMessages: Record<string, IIPCMessageProcessorWorkerRecord> = { };
30
- #messageHeader: string;
31
-
32
- constructor(options: IPCMessageManagerOptions) {
33
- this.#id = uuidv4();
34
- this.#options = options;
35
- this.#messageHeader = `__STS__${this.#options.namespace}__${uuidv4()}`;
36
- }
37
-
38
- get id() {
39
- return this.#id;
40
- }
41
-
42
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
43
- ReceivedMessageFromMaster(msg: any) {
44
- // Override in subclass if required
45
- }
46
-
47
- SendMessage = (payload: JSONObject, options?: any): Promise<JSONObject> => {
48
- return new Promise((resolve, reject) => {
49
- this.#SendMessage(payload, options,
50
- (payload: IIPCMessageProcessorIPCPayload) => {
51
- resolve(payload.responsePayload);
52
- },
53
- (payload: IIPCMessageProcessorIPCPayload) => {
54
- reject(payload.requestPayload);
55
- })
56
- })
57
- }
58
-
59
- #SendMessage = (payload: JSONObject, options: any,
60
- callBack: (payload: IIPCMessageProcessorIPCPayload) => void,
61
- errorCallBack: (payload: IIPCMessageProcessorIPCPayload) => void
62
- ): void => {
63
- const messageId: string = uuidv4();
64
- const requestPayload: IIPCMessageProcessorIPCPayload = {
65
- header: this.#messageHeader,
66
- messageId,
67
- senderId: this.#id,
68
- senderRole: this.#options.role,
69
- requestPayload: payload,
70
- responsePayload: { },
71
- pid: process.pid.toString(),
72
- messageType: 'REQUEST'
73
- }
74
- const messageRecord = {
75
- messageId,
76
- senderId: this.#id,
77
- senderRole: this.#options.role,
78
- requestPayload,
79
- responses: { }, // record
80
- startTime: performance.now(),
81
- endTime: 0,
82
- timeout: setTimeout(() => {
83
- //this.#LogDebugMessage(chalk.red(`Timeout has occurred after: [${this.#options.requestResponseMessageTimeout}]ms with message id: [${messageRecord.messageId}]. Details: [${JSON.stringify(this.#inflightMessages[messageRecord.messageId].requestPayload)}]`));
84
- setTimeout(() => {
85
- delete this.#inflightMessages[messageRecord.messageId];
86
- }, 0).unref();
87
- errorCallBack(requestPayload);
88
- }, this.#options.requestResponseMessageTimeout).unref(),// max message timeout allowed
89
- callBack,
90
- errorCallBack
91
- }
92
- this.#inflightMessages[messageRecord.messageId] = messageRecord;
93
- //this.#LogDebugMessage(chalk.cyan(`sending: [${JSON.stringify(requestPayload)}]`));
94
- this.#options.messageSender(requestPayload, options);
95
- }
96
-
97
- #ProcessMessage = async (msg: any, options: any): Promise<void> => {
98
- if (msg.header && msg.header.localeCompare(this.#messageHeader) === 0) {
99
- const message = (msg as IIPCMessageProcessorIPCPayload);
100
- if (this.#inflightMessages[message.messageId]) {
101
- const inFlightMessageRecord: IIPCMessageProcessorWorkerRecord = this.#inflightMessages[message.messageId];
102
- inFlightMessageRecord.responses[message.senderId ] = { ...message };
103
- let completed = true; // Defaults to true
104
- if (this.#options.ProcessResponseMessage) {
105
- completed = await this.#options.ProcessResponseMessage(inFlightMessageRecord.responses, options);
106
- if (completed) {
107
- inFlightMessageRecord.endTime = performance.now();
108
- clearTimeout(inFlightMessageRecord.timeout as NodeJS.Timeout);
109
- inFlightMessageRecord.callBack({
110
- responsePayload: Object.values(inFlightMessageRecord.responses).map(r => r.responsePayload)
111
- } as any, options) //
112
- delete this.#inflightMessages[message.messageId];
113
- }
114
- } else if (completed) {
115
- inFlightMessageRecord.endTime = performance.now();
116
- clearTimeout(inFlightMessageRecord.timeout as NodeJS.Timeout);
117
- inFlightMessageRecord.callBack(message, options) // inFlightMessageRecord.responses
118
- //@@inFlightMessageRecord.callBack(Object.values(inFlightMessageRecord.responses), options) //
119
- delete this.#inflightMessages[message.messageId];
120
- } else {
121
- //console.log(chalk.grey(`#ProcessMessage:5`));
122
- }
123
- } else {
124
- //throw new Error(`Could not find Request/Response message with id: [${message.messageId}]`); //@@
125
- }
126
- }
127
- }
128
-
129
- Start = (options?: any) => {
130
- this.#messageHeader = `__STS__${this.#options.namespace}__${uuidv4()}`;
131
- this.#options.messageReceiverStart(options);
132
- }
133
-
134
- Stop = (options?: any) => {
135
- // Kill in-flight messages
136
- this.#options.messageReceiverStop(options);
137
-
138
- for (const [, iPCMessageProcessorWorkerRecord] of Object.entries(this.#inflightMessages)) {
139
- if (iPCMessageProcessorWorkerRecord.timeout) {
140
- clearTimeout(iPCMessageProcessorWorkerRecord.timeout);
141
- }
142
- }
143
- this.#inflightMessages = { };
144
- }
145
-
146
- // Process a message recieved from a worker
147
- ProcessMessage = async (msg: any, options: any) => {
148
- if (msg.header) {
149
- const checkName = `__STS__${this.#options.namespace}__`; //@@ this is a broadcast becuase the unique uuid is not part of the header test
150
- if ((msg.header as string).includes(checkName)) {
151
- const message = (msg as IIPCMessageProcessorIPCPayload);
152
- if (msg.messageType.localeCompare('REQUEST') === 0) {
153
- let processMessage = true;
154
- if (message.requestPayload.args && message.requestPayload.args.length > 0 && message.requestPayload.args[0].group) {
155
- const group = message.requestPayload.args[0].group;
156
- processMessage = (this.#options.groups.indexOf(group) === -1) ? false : true;
157
- }
158
- if (processMessage) {
159
- message.responsePayload = await this.#options.ProcessRequestMessage(message, options);
160
- message.senderId = this.#id;
161
- message.messageType = 'RESPONSE';
162
- this.#options.messageSender(message, options);
163
- }
164
- } else {
165
- // Received a response (to my request)
166
- this.#ProcessMessage(msg, options);
167
- }
168
- }
169
- }
170
- }
171
- }
@@ -1,76 +0,0 @@
1
- /* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF
2
- import { ISTSLogger, JSONObject, defaultLogger } from '@nsshunt/stsutils'
3
-
4
- import { Worker } from 'node:cluster';
5
-
6
- import { IIPCMessageProcessorIPCPayload } from './commonTypes'
7
-
8
- import { IPCMessageManager, IPCMessageManagerOptions } from './ipcMessageManager'
9
-
10
- export interface IIPCMessageProcessorPrimary {
11
- logger: ISTSLogger
12
- namespace: string
13
- processPayload?: (payload: IIPCMessageProcessorIPCPayload, options: any) => Promise<JSONObject>
14
- }
15
-
16
- /**
17
- * IPC Message Handling.
18
- *
19
- * This class can be used to support messages between cluster.primary and cluster.worker instances using IPC.
20
- * This class can be used for finer control for processing messages between the cluster primary and cluster workers.
21
- * Use the ipcMessageHandler for a simpler implementation.
22
- * This class is used for the cluster primary thread only.
23
- * Note: Currently groups handling is not supported. Use the redis version for this capability.
24
- */
25
- export class IPCMessageProcessorPrimary {
26
- #ipcMessageManager: IPCMessageManager;
27
- #worker: Worker | null = null;
28
-
29
- constructor(classOptions: IIPCMessageProcessorPrimary) {
30
- const ipcMessageManagerOptions: IPCMessageManagerOptions = {
31
- logger: defaultLogger,
32
- requestResponseMessageTimeout: 5000,
33
- namespace: classOptions.namespace,
34
- role: 'SERVER',
35
- messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => {
36
- (options.worker as any).send(payload);
37
- },
38
- ProcessRequestMessage: async (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {
39
- if (classOptions.processPayload) {
40
- return classOptions.processPayload(payload, options);
41
- } else {
42
- return { };
43
- }
44
- },
45
- messageReceiverStart: (options: any) => {
46
- // Receive a message to process from a worker
47
- const worker = (options.worker as Worker);
48
- worker.on('message', (payload) => this.#ipcMessageManager.ProcessMessage(payload, { worker }));
49
- },
50
- messageReceiverStop: (options: any) => {
51
- const worker = (options.worker as Worker);
52
- worker.off('message', (payload) => this.#ipcMessageManager.ProcessMessage(payload, { worker }));
53
- },
54
- groups: [ ]
55
- }
56
- this.#ipcMessageManager = new IPCMessageManager(ipcMessageManagerOptions);
57
- }
58
-
59
- SendMessage = async (payload: JSONObject): Promise<JSONObject> => {
60
- return this.#ipcMessageManager.SendMessage(payload, { worker: this.#worker });
61
- }
62
-
63
- Start = (worker: Worker) => {
64
- this.#ipcMessageManager.Start({ worker });
65
- this.#worker = worker;
66
- }
67
-
68
- Stop = () => {
69
- this.#ipcMessageManager.Stop({ worker: this.#worker });
70
- this.#worker = null;
71
- }
72
-
73
- get worker(): Worker | null {
74
- return this.#worker;
75
- }
76
- }
@@ -1,70 +0,0 @@
1
- /* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF
2
- import { ISTSLogger, JSONObject, defaultLogger } from '@nsshunt/stsutils'
3
-
4
- import { IIPCMessageProcessorIPCPayload } from './commonTypes'
5
-
6
- import { IPCMessageManager, IPCMessageManagerOptions } from './ipcMessageManager'
7
-
8
- export interface IIPCMessageProcessorWorker {
9
- logger: ISTSLogger
10
- requestResponseMessageTimeout: number
11
- namespace: string
12
- processPayload?: (payload: IIPCMessageProcessorIPCPayload, options: any) => Promise<JSONObject>
13
- }
14
-
15
- /**
16
- * IPC Message Handling.
17
- *
18
- * This class can be used to support messages between cluster.primary and cluster.worker instances using IPC.
19
- * This class can be used for finer control for processing messages between the cluster primary and cluster workers.
20
- * Use the ipcMessageHandler for a simpler implementation.
21
- * This class is used for the cluster worker threads only.
22
- * Note: Currently groups handling is not supported. Use the redis version for this capability.
23
- */
24
- export class IPCMessageProcessorWorker {
25
- #ipcMessageManager: IPCMessageManager;
26
-
27
- constructor(classOptions: IIPCMessageProcessorWorker) {
28
- const ipcMessageManagerOptions: IPCMessageManagerOptions = {
29
- logger: defaultLogger,
30
- requestResponseMessageTimeout: classOptions.requestResponseMessageTimeout,
31
- namespace: classOptions.namespace,
32
- role: 'CLIENT',
33
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
34
- messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => {
35
- // Options not required for sending payloads to the master process
36
- (process as any).send(payload);
37
- },
38
- ProcessRequestMessage: async (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {
39
- if (classOptions.processPayload) {
40
- return classOptions.processPayload(payload, options);
41
- } else {
42
- return { };
43
- }
44
- },
45
- messageReceiverStart: (options: any) => {
46
- // Receive a message response back from the primary thread
47
- process.on('message', (payload) => {
48
- this.#ipcMessageManager.ProcessMessage(payload, options);
49
- });
50
- },
51
- messageReceiverStop: (options: any) => {
52
- process.off('message', (payload) => this.#ipcMessageManager.ProcessMessage(payload, options));
53
- },
54
- groups: [ ]
55
- }
56
- this.#ipcMessageManager = new IPCMessageManager(ipcMessageManagerOptions);
57
- }
58
-
59
- SendMessage = async (payload: JSONObject): Promise<JSONObject> => {
60
- return this.#ipcMessageManager.SendMessage(payload, { });
61
- }
62
-
63
- Start = () => {
64
- this.#ipcMessageManager.Start({ });
65
- }
66
-
67
- Stop = () => {
68
- this.#ipcMessageManager.Stop({ });
69
- }
70
- }
@@ -1,341 +0,0 @@
1
- /* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF */ // --> OFF
2
- import { TinyEmitter } from "tiny-emitter";
3
- import { ISTSLogger, JSONObject } from '@nsshunt/stsutils'
4
-
5
- import { IIPCMessageProcessorIPCPayload, IServiceProcessContext, ProcessOptions } from '../commonTypes'
6
-
7
- import { IPCMessageManager, IPCMessageManagerOptions } from '../ipcMessageManager'
8
-
9
- import chalk from 'chalk';
10
-
11
- import { MessagePort } from 'worker_threads';
12
-
13
- export interface IWebWorderMessageHandlerOptions {
14
- logger: ISTSLogger
15
- role: 'SERVER' | 'CLIENT'
16
- namespace: string
17
- groups: string[]
18
- ignoreEvents?: string[]
19
- processOptions?: ProcessOptions
20
- messagePort: MessagePort
21
- }
22
-
23
- export interface IClientRecord {
24
- id: string
25
- clientConnected: Date
26
- pingCount: number
27
- timeout: NodeJS.Timeout
28
- groups: string[]
29
- serviceProcessContext?: IServiceProcessContext
30
- }
31
-
32
- export interface IEventPayload {
33
- __eventName: string
34
- args: any[]
35
- }
36
-
37
- export interface IEventRecord {
38
- event: string
39
- callback: any,
40
- ctx?: any
41
- }
42
-
43
- export interface IPingData {
44
- id: string
45
- groups: string[]
46
- serviceProcessContext?: IServiceProcessContext
47
- }
48
-
49
- export class WebWorkerMessageHandler extends TinyEmitter {
50
- #ipcMessageManager: IPCMessageManager | null = null;
51
- #options: IWebWorderMessageHandlerOptions;
52
- #events: Record<string, IEventRecord> = { };
53
- #clients: Record<string, IClientRecord> = { };
54
- #pingTimeout: NodeJS.Timeout | null = null;
55
- #messagePort: MessagePort;
56
-
57
- constructor(options: IWebWorderMessageHandlerOptions) {
58
- super();
59
- this.#options = options;
60
- this.#messagePort = options.messagePort;
61
-
62
- this.SetupPrimary();
63
-
64
- if (this.#options.role.localeCompare('CLIENT') === 0) {
65
- const ping = () => {
66
- this.#pingTimeout = setTimeout(() => {
67
- const pingData: IPingData = {
68
- id: (this.#ipcMessageManager as IPCMessageManager).id,
69
- groups: this.#options.groups,
70
- }
71
- if (this.#options.processOptions) {
72
- pingData.serviceProcessContext = this.#options.processOptions.serviceProcessContext;
73
- }
74
- this.emit('ping', pingData, (response: any) => { });
75
- ping();
76
- }, 1000).unref();
77
- }
78
- ping();
79
- } else {
80
- this.on('ping', (pingData: IPingData, callback: any) => {
81
- const { id, groups, serviceProcessContext } = pingData;
82
- if (this.#clients[id]) {
83
- clearTimeout(this.#clients[id].timeout);
84
- this.#clients[id].pingCount++;
85
- this.#clients[id].timeout = setTimeout(() => {
86
- delete this.#clients[id];
87
- }, 2000);
88
- this.#clients[id].groups = groups;
89
- this.#clients[id].serviceProcessContext = serviceProcessContext;
90
- } else {
91
- this.#clients[id] = {
92
- id,
93
- clientConnected: new Date(),
94
- pingCount: 0,
95
- timeout: setTimeout(() => {
96
- delete this.#clients[id];
97
- }, 2000),
98
- groups,
99
- serviceProcessContext
100
- }
101
- }
102
- callback('ok');
103
- });
104
- }
105
- }
106
-
107
- #processRawMessage = (rawmessage: string) => {
108
- const message = JSON.parse(rawmessage);
109
- this.#ipcMessageManager?.ProcessMessage(message, { });
110
- }
111
-
112
- get clients(): Record<string, IClientRecord> {
113
- return this.#clients;
114
- }
115
-
116
- get groups(): string[] {
117
- return this.#options.groups;
118
- }
119
-
120
- AddGroup = (group: string) => {
121
- const index = this.#options.groups.indexOf(group);
122
- if (index === -1) {
123
- this.#options.groups.push(group);
124
- }
125
- }
126
-
127
- RemoveGroup = (group: string) => {
128
- const removeIndex = this.#options.groups.indexOf(group);
129
- if (removeIndex !== -1) {
130
- this.#options.groups.splice(removeIndex, 1);
131
- }
132
- }
133
-
134
- SetupPrimary = () => {
135
- const ipcMessageManagerOptions: IPCMessageManagerOptions = {
136
- logger: this.#options.logger,
137
- requestResponseMessageTimeout: 5000,
138
- namespace: this.#options.namespace,
139
- role: this.#options.role,
140
- messageSender: this.#messageSender,
141
- groups: this.#options.groups,
142
- // This method is used to calculate if all responses have been received from multiple clients (broadcast)
143
- // returns true/false.
144
- ProcessResponseMessage: this.#ProcessResponseMessage,
145
- // This gets called when an event is received from a message receiver (when ProcessMessage is invoked from the receiver event handler)
146
- ProcessRequestMessage: this.#processPayload,
147
-
148
- messageReceiverStart: (options: any) => {
149
- this.#messagePort.on('message', this.#processRawMessage);
150
- //this.#redisSubscriber.on("message", this.#processRawMessage);
151
- },
152
-
153
- messageReceiverStop: (options: any) => {
154
- this.#messagePort.off("message", this.#processRawMessage);
155
- //this.#redisSubscriber.off("message", this.#processRawMessage);
156
- }
157
- }
158
- this.#ipcMessageManager = new IPCMessageManager(ipcMessageManagerOptions);
159
- }
160
-
161
-
162
- #messageSender = (payload: IIPCMessageProcessorIPCPayload, options: any) => {
163
- if (payload.messageType.localeCompare('REQUEST') === 0) {
164
- //this.#redisPublisher.publish(this.#requestChannel, JSON.stringify(payload));
165
- this.#messagePort.postMessage(JSON.stringify(payload));
166
- } else if (payload.messageType.localeCompare('RESPONSE') === 0) {
167
- this.#messagePort.postMessage(JSON.stringify(payload));
168
- //this.#redisPublisher.publish(this.#responseChannel, JSON.stringify(payload));
169
- }
170
- }
171
-
172
-
173
- #ProcessResponseMessage = async (responses: Record<string, IIPCMessageProcessorIPCPayload>, options: any): Promise<boolean> => {
174
- // Now check if we have all responses ...
175
- let allFound = false;
176
-
177
- for (const [responseId, response] of Object.entries(responses)) {
178
- if (response.senderRole.localeCompare('CLIENT') === 0) {
179
- allFound = true;
180
- break;
181
- }
182
- }
183
- if (allFound) {
184
- return allFound;
185
- }
186
-
187
- let found = true;
188
-
189
- // Sender role here is SERVER
190
- let requestGroup = null;
191
- for (const [responseId, response] of Object.entries(responses)) {
192
- if (response.requestPayload.args.length > 0 && response.requestPayload.args[0].group) {
193
- requestGroup = response.requestPayload.args[0].group;
194
- break;
195
- }
196
- }
197
-
198
- if (requestGroup) {
199
- const clientsInGroup = Object.values(this.#clients).filter(c => {
200
- if (c.groups.indexOf(requestGroup) === -1) {
201
- return false;
202
- }
203
- return true;
204
- });
205
-
206
- // Now make sure that all clients are in the responses
207
- found = true;
208
- clientsInGroup.forEach(c => {
209
- if (!responses[c.id]) {
210
- found = false;
211
- }
212
- })
213
- } else {
214
- const clientsInGroup = Object.values(this.#clients)
215
-
216
- // Now make sure that all clients are in the responses
217
- found = true;
218
- clientsInGroup.forEach(c => {
219
- if (!responses[c.id]) {
220
- found = false;
221
- }
222
- })
223
- }
224
-
225
- return found;
226
- }
227
-
228
- #processPayload = (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {
229
- // check the event name from the collection and invoke that function
230
- return new Promise<JSONObject>((resolve, reject) => {
231
- if (payload.messageType.localeCompare('REQUEST') === 0) {
232
- if (payload.requestPayload['__eventName']) {
233
- const eventName = payload.requestPayload['__eventName'];
234
- // Only process events that I have registered interest in (using .on)
235
- if (this.#events[eventName]) {
236
- try {
237
- //const retVal = this.#events[eventName].callback(payload.requestPayload.args, payload, options, this.#events[eventName].ctx);
238
- this.#events[eventName].callback(...payload.requestPayload.args, (responseMessage: any) => {
239
- resolve(responseMessage);
240
- });
241
- } catch (error) {
242
- reject(error);
243
- }
244
- }
245
- }
246
- }
247
- });
248
- }
249
-
250
- // p.on('fromworker', (arg1: number, arg2: string, callback: any) => {
251
- override on(event: string, callback: any, ctx?: any): this {
252
- if (this.#events[event]) {
253
- // Update the event with the same name
254
- delete this.#events[event];
255
- }
256
- const eventObject: IEventRecord = {
257
- event,
258
- callback,
259
- ctx
260
- }
261
- this.#events[eventObject.event] = eventObject;
262
- return this;
263
- }
264
-
265
- override off(event: string, callback?: any): this {
266
- if (this.#events[event]) {
267
- delete this.#events[event];
268
- }
269
- return this;
270
- }
271
-
272
- Start = () => {
273
- this.#ipcMessageManager?.Start();
274
- }
275
-
276
- Stop = () => {
277
- if (this.#pingTimeout) {
278
- clearTimeout(this.#pingTimeout);
279
- this.#pingTimeout = null;
280
- }
281
-
282
- this.#ipcMessageManager?.Stop();
283
-
284
- /*
285
- this.#redisSubscriber.quit();
286
- this.#redisSubscriber.disconnect();
287
-
288
- this.#redisPublisher.quit();
289
- this.#redisPublisher.disconnect();
290
- */
291
- }
292
-
293
- override emit(event: string, ...args: any[]): this {
294
- (async () => {
295
- try {
296
- const retVal = await this.#ipcMessageManager?.SendMessage({
297
- __eventName: event,
298
- args: args.slice(0, args.length-1)
299
- } as IEventPayload);
300
- // Invoke the response callback
301
- args[args.length-1](retVal);
302
- } catch (error) {
303
- if (this.#options.ignoreEvents) {
304
- if (this.#options.ignoreEvents.indexOf((error as any).__eventName) !== -1) {
305
- return;
306
- }
307
- }
308
- this.#options.logger.error(chalk.red(`RedisMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));
309
- }
310
- })();
311
- return this;
312
- }
313
-
314
- emitWithError(event: string, args: JSONObject, responseCb: (response: JSONObject | undefined) => void, errorCb: (error: any) => void): this {
315
- (async () => {
316
- try {
317
- const retVal = await this.#ipcMessageManager?.SendMessage({
318
- __eventName: event,
319
- args: [ args ]
320
- } as IEventPayload);
321
- // Invoke the response callback
322
- responseCb(retVal);
323
- } catch (error) {
324
- if (this.#options.ignoreEvents) {
325
- if (this.#options.ignoreEvents.indexOf((error as any).__eventName) !== -1) {
326
- return;
327
- }
328
- }
329
- errorCb(error);
330
- }
331
- })();
332
- return this;
333
- }
334
-
335
- emitex = async(event: string, ...args: any[]): Promise<JSONObject> => {
336
- return (this.#ipcMessageManager as IPCMessageManager).SendMessage({
337
- __eventName: event,
338
- args
339
- } as IEventPayload);
340
- }
341
- }