@nsshunt/stsappframework 3.1.209 → 3.1.210
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build.sh +5 -0
- package/dist/index.js +0 -5
- package/dist/index.js.map +1 -1
- package/dist/masterprocessbase.js +3 -53
- package/dist/masterprocessbase.js.map +1 -1
- package/dist/processbase.js +4 -17
- package/dist/processbase.js.map +1 -1
- package/dist/testing/app.js +0 -457
- package/dist/testing/app.js.map +1 -1
- package/dist/workerprocessbase.js +1 -36
- package/dist/workerprocessbase.js.map +1 -1
- package/package.json +14 -13
- package/src/commonTypes.ts +2 -2
- package/src/index.ts +0 -5
- package/src/masterprocessbase.ts +4 -18
- package/src/processbase.ts +7 -22
- package/src/testing/app.ts +1 -530
- package/src/workerprocessbase.ts +1 -40
- package/types/commonTypes.d.ts +0 -2
- package/types/commonTypes.d.ts.map +1 -1
- package/types/index.d.ts +0 -5
- package/types/index.d.ts.map +1 -1
- package/types/masterprocessbase.d.ts.map +1 -1
- package/types/processbase.d.ts +0 -2
- package/types/processbase.d.ts.map +1 -1
- package/types/workerprocessbase.d.ts.map +1 -1
- package/dist/ipcMessageHandler.js +0 -189
- package/dist/ipcMessageHandler.js.map +0 -1
- package/dist/ipcMessageManager.js +0 -146
- package/dist/ipcMessageManager.js.map +0 -1
- package/dist/ipcMessageProcessorPrimary.js +0 -65
- package/dist/ipcMessageProcessorPrimary.js.map +0 -1
- package/dist/ipcMessageProcessorWorker.js +0 -61
- package/dist/ipcMessageProcessorWorker.js.map +0 -1
- package/dist/messagehandling/webWorkerMessageHandler.js +0 -280
- package/dist/messagehandling/webWorkerMessageHandler.js.map +0 -1
- package/dist/messagehandling/webWorkerSupport.js +0 -62
- package/dist/messagehandling/webWorkerSupport.js.map +0 -1
- package/dist/redisMessageHandler.js +0 -305
- package/dist/redisMessageHandler.js.map +0 -1
- package/dist/redisMessageHandler.test.js +0 -129
- package/dist/redisMessageHandler.test.js.map +0 -1
- package/dist/testing/app_ipc_legacy.js +0 -84
- package/dist/testing/app_ipc_legacy.js.map +0 -1
- package/dist/testing/app_ipcex.js +0 -69
- package/dist/testing/app_ipcex.js.map +0 -1
- package/dist/testing/app_ww.js +0 -54
- package/dist/testing/app_ww.js.map +0 -1
- package/src/ipcMessageHandler.ts +0 -201
- package/src/ipcMessageManager.ts +0 -171
- package/src/ipcMessageProcessorPrimary.ts +0 -76
- package/src/ipcMessageProcessorWorker.ts +0 -70
- package/src/messagehandling/webWorkerMessageHandler.ts +0 -341
- package/src/messagehandling/webWorkerSupport.ts +0 -66
- package/src/redisMessageHandler.test.ts +0 -157
- package/src/redisMessageHandler.ts +0 -371
- package/src/testing/app_ipc_legacy.ts +0 -87
- package/src/testing/app_ipcex.ts +0 -68
- package/src/testing/app_ww.ts +0 -68
- package/types/ipcMessageHandler.d.ts +0 -30
- package/types/ipcMessageHandler.d.ts.map +0 -1
- package/types/ipcMessageManager.d.ts +0 -30
- package/types/ipcMessageManager.d.ts.map +0 -1
- package/types/ipcMessageProcessorPrimary.d.ts +0 -26
- package/types/ipcMessageProcessorPrimary.d.ts.map +0 -1
- package/types/ipcMessageProcessorWorker.d.ts +0 -25
- package/types/ipcMessageProcessorWorker.d.ts.map +0 -1
- package/types/messagehandling/webWorkerMessageHandler.d.ts +0 -52
- package/types/messagehandling/webWorkerMessageHandler.d.ts.map +0 -1
- package/types/messagehandling/webWorkerSupport.d.ts +0 -6
- package/types/messagehandling/webWorkerSupport.d.ts.map +0 -1
- package/types/redisMessageHandler.d.ts +0 -51
- package/types/redisMessageHandler.d.ts.map +0 -1
- package/types/redisMessageHandler.test.d.ts +0 -2
- package/types/redisMessageHandler.test.d.ts.map +0 -1
- package/types/testing/app_ipc_legacy.d.ts +0 -2
- package/types/testing/app_ipc_legacy.d.ts.map +0 -1
- package/types/testing/app_ipcex.d.ts +0 -2
- package/types/testing/app_ipcex.d.ts.map +0 -1
- package/types/testing/app_ww.d.ts +0 -2
- package/types/testing/app_ww.d.ts.map +0 -1
|
@@ -1,371 +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
|
-
import { Redis, RedisOptions } from "ioredis";
|
|
9
|
-
|
|
10
|
-
import chalk from 'chalk';
|
|
11
|
-
|
|
12
|
-
const REQUEST_CHANNEL = '__STS__SVC_stsappframework_request'
|
|
13
|
-
const RESPONSE_CHANNEL = '__STS__SVC_stsappframework_response'
|
|
14
|
-
|
|
15
|
-
export interface IRedisAdminManagerOptions {
|
|
16
|
-
redisUrl: string
|
|
17
|
-
logger: ISTSLogger
|
|
18
|
-
role: 'SERVER' | 'CLIENT'
|
|
19
|
-
namespace: string
|
|
20
|
-
groups: string[]
|
|
21
|
-
ignoreEvents?: string[]
|
|
22
|
-
processOptions?: ProcessOptions
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface IClientRecord {
|
|
26
|
-
id: string
|
|
27
|
-
clientConnected: Date
|
|
28
|
-
pingCount: number
|
|
29
|
-
timeout: NodeJS.Timeout
|
|
30
|
-
groups: string[]
|
|
31
|
-
serviceProcessContext?: IServiceProcessContext
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface IEventPayload {
|
|
35
|
-
__eventName: string
|
|
36
|
-
args: any[]
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface IEventRecord {
|
|
40
|
-
event: string
|
|
41
|
-
callback: any,
|
|
42
|
-
ctx?: any
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface IPingData {
|
|
46
|
-
id: string
|
|
47
|
-
groups: string[]
|
|
48
|
-
serviceProcessContext?: IServiceProcessContext
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export class RedisMessageHandler extends TinyEmitter {
|
|
52
|
-
#ipcMessageManager: IPCMessageManager | null = null;
|
|
53
|
-
#options: IRedisAdminManagerOptions;
|
|
54
|
-
#events: Record<string, IEventRecord> = { };
|
|
55
|
-
#requestChannel: string;
|
|
56
|
-
#responseChannel: string;
|
|
57
|
-
#redisSubscriber: Redis;
|
|
58
|
-
#redisPublisher: Redis;
|
|
59
|
-
#clients: Record<string, IClientRecord> = { };
|
|
60
|
-
#pingTimeout: NodeJS.Timeout | null = null;
|
|
61
|
-
|
|
62
|
-
constructor(options: IRedisAdminManagerOptions) {
|
|
63
|
-
super();
|
|
64
|
-
this.#options = options;
|
|
65
|
-
|
|
66
|
-
this.#requestChannel = REQUEST_CHANNEL
|
|
67
|
-
this.#responseChannel = RESPONSE_CHANNEL
|
|
68
|
-
|
|
69
|
-
const redisOptions: RedisOptions = {
|
|
70
|
-
showFriendlyErrorStack: true,
|
|
71
|
-
maxRetriesPerRequest: 20
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
this.#redisSubscriber = new Redis(this.#options.redisUrl, redisOptions);
|
|
75
|
-
this.#redisPublisher = new Redis(this.#options.redisUrl, redisOptions);
|
|
76
|
-
|
|
77
|
-
this.#redisSubscriber.subscribe(this.#requestChannel, this.#responseChannel, (error, count) => {
|
|
78
|
-
if (error) {
|
|
79
|
-
// Just like other commands, subscribe() can fail for some reasons, // ex network issues.
|
|
80
|
-
this.#LogError(chalk.red(`RedisAdminManager:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Error - Failed to subscribe: [${error}]`));
|
|
81
|
-
} else {
|
|
82
|
-
// `count` represents the number of channels this client is currently subscribed to.
|
|
83
|
-
this.#LogInfo(chalk.white(`RedisAdminManager:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Subscribed successfully! This client is currently subscribed to ${count} channels.`));
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
this.SetupPrimary();
|
|
88
|
-
|
|
89
|
-
if (this.#options.role.localeCompare('CLIENT') === 0) {
|
|
90
|
-
const ping = () => {
|
|
91
|
-
this.#pingTimeout = setTimeout(() => {
|
|
92
|
-
const pingData: IPingData = {
|
|
93
|
-
id: (this.#ipcMessageManager as IPCMessageManager).id,
|
|
94
|
-
groups: this.#options.groups,
|
|
95
|
-
}
|
|
96
|
-
if (this.#options.processOptions) {
|
|
97
|
-
pingData.serviceProcessContext = this.#options.processOptions.serviceProcessContext;
|
|
98
|
-
}
|
|
99
|
-
this.emit('ping', pingData, (response: any) => { });
|
|
100
|
-
ping();
|
|
101
|
-
}, 1000).unref();
|
|
102
|
-
}
|
|
103
|
-
ping();
|
|
104
|
-
} else {
|
|
105
|
-
this.on('ping', (pingData: IPingData, callback: any) => {
|
|
106
|
-
const { id, groups, serviceProcessContext } = pingData;
|
|
107
|
-
if (this.#clients[id]) {
|
|
108
|
-
clearTimeout(this.#clients[id].timeout);
|
|
109
|
-
this.#clients[id].pingCount++;
|
|
110
|
-
this.#clients[id].timeout = setTimeout(() => {
|
|
111
|
-
delete this.#clients[id];
|
|
112
|
-
}, 2000);
|
|
113
|
-
this.#clients[id].groups = groups;
|
|
114
|
-
this.#clients[id].serviceProcessContext = serviceProcessContext;
|
|
115
|
-
} else {
|
|
116
|
-
this.#clients[id] = {
|
|
117
|
-
id,
|
|
118
|
-
clientConnected: new Date(),
|
|
119
|
-
pingCount: 0,
|
|
120
|
-
timeout: setTimeout(() => {
|
|
121
|
-
delete this.#clients[id];
|
|
122
|
-
}, 2000),
|
|
123
|
-
groups,
|
|
124
|
-
serviceProcessContext
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
callback('ok');
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
#LogInfo(message: any) {
|
|
133
|
-
this.#options.logger.info(message);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
#LogError(message: any) {
|
|
137
|
-
this.#options.logger.error(message);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
#processRawMessage = (channel: string, rawmessage: string) => {
|
|
141
|
-
const message = JSON.parse(rawmessage);
|
|
142
|
-
this.#ipcMessageManager?.ProcessMessage(message, { channel });
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
get clients(): Record<string, IClientRecord> {
|
|
146
|
-
return this.#clients;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
get groups(): string[] {
|
|
150
|
-
return this.#options.groups;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
AddGroup = (group: string) => {
|
|
154
|
-
const index = this.#options.groups.indexOf(group);
|
|
155
|
-
if (index === -1) {
|
|
156
|
-
this.#options.groups.push(group);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
RemoveGroup = (group: string) => {
|
|
161
|
-
const removeIndex = this.#options.groups.indexOf(group);
|
|
162
|
-
if (removeIndex !== -1) {
|
|
163
|
-
this.#options.groups.splice(removeIndex, 1);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
SetupPrimary = () => {
|
|
168
|
-
const ipcMessageManagerOptions: IPCMessageManagerOptions = {
|
|
169
|
-
logger: this.#options.logger,
|
|
170
|
-
requestResponseMessageTimeout: 5000,
|
|
171
|
-
namespace: this.#options.namespace,
|
|
172
|
-
role: this.#options.role,
|
|
173
|
-
messageSender: this.#messageSender,
|
|
174
|
-
groups: this.#options.groups,
|
|
175
|
-
// This method is used to calculate if all responses have been received from multiple clients (broadcast)
|
|
176
|
-
// returns true/false.
|
|
177
|
-
ProcessResponseMessage: this.#ProcessResponseMessage,
|
|
178
|
-
// This gets called when an event is received from a message receiver (when ProcessMessage is invoked from the receiver event handler)
|
|
179
|
-
ProcessRequestMessage: this.#processPayload,
|
|
180
|
-
|
|
181
|
-
messageReceiverStart: (options: any) => {
|
|
182
|
-
this.#redisSubscriber.on("message", this.#processRawMessage);
|
|
183
|
-
},
|
|
184
|
-
|
|
185
|
-
messageReceiverStop: (options: any) => {
|
|
186
|
-
this.#redisSubscriber.off("message", this.#processRawMessage);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
this.#ipcMessageManager = new IPCMessageManager(ipcMessageManagerOptions);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
#messageSender = (payload: IIPCMessageProcessorIPCPayload, options: any) => {
|
|
194
|
-
if (payload.messageType.localeCompare('REQUEST') === 0) {
|
|
195
|
-
this.#redisPublisher.publish(this.#requestChannel, JSON.stringify(payload));
|
|
196
|
-
} else if (payload.messageType.localeCompare('RESPONSE') === 0) {
|
|
197
|
-
this.#redisPublisher.publish(this.#responseChannel, JSON.stringify(payload));
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
#ProcessResponseMessage = async (responses: Record<string, IIPCMessageProcessorIPCPayload>, options: any): Promise<boolean> => {
|
|
203
|
-
// Now check if we have all responses ...
|
|
204
|
-
let allFound = false;
|
|
205
|
-
|
|
206
|
-
for (const [responseId, response] of Object.entries(responses)) {
|
|
207
|
-
if (response.senderRole.localeCompare('CLIENT') === 0) {
|
|
208
|
-
allFound = true;
|
|
209
|
-
break;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
if (allFound) {
|
|
213
|
-
return allFound;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
let found = true;
|
|
217
|
-
|
|
218
|
-
// Sender role here is SERVER
|
|
219
|
-
let requestGroup = null;
|
|
220
|
-
for (const [responseId, response] of Object.entries(responses)) {
|
|
221
|
-
if (response.requestPayload.args.length > 0 && response.requestPayload.args[0].group) {
|
|
222
|
-
requestGroup = response.requestPayload.args[0].group;
|
|
223
|
-
break;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (requestGroup) {
|
|
228
|
-
const clientsInGroup = Object.values(this.#clients).filter(c => {
|
|
229
|
-
if (c.groups.indexOf(requestGroup) === -1) {
|
|
230
|
-
return false;
|
|
231
|
-
}
|
|
232
|
-
return true;
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
// Now make sure that all clients are in the responses
|
|
236
|
-
found = true;
|
|
237
|
-
clientsInGroup.forEach(c => {
|
|
238
|
-
if (!responses[c.id]) {
|
|
239
|
-
found = false;
|
|
240
|
-
}
|
|
241
|
-
})
|
|
242
|
-
} else {
|
|
243
|
-
const clientsInGroup = Object.values(this.#clients)
|
|
244
|
-
|
|
245
|
-
// Now make sure that all clients are in the responses
|
|
246
|
-
found = true;
|
|
247
|
-
clientsInGroup.forEach(c => {
|
|
248
|
-
if (!responses[c.id]) {
|
|
249
|
-
found = false;
|
|
250
|
-
}
|
|
251
|
-
})
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
return found;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
#processPayload = (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {
|
|
258
|
-
// check the event name from the collection and invoke that function
|
|
259
|
-
return new Promise<JSONObject>((resolve, reject) => {
|
|
260
|
-
if (payload.messageType.localeCompare('REQUEST') === 0) {
|
|
261
|
-
if (payload.requestPayload['__eventName']) {
|
|
262
|
-
const eventName = payload.requestPayload['__eventName'];
|
|
263
|
-
// Only process events that I have registered interest in (using .on)
|
|
264
|
-
if (this.#events[eventName]) {
|
|
265
|
-
try {
|
|
266
|
-
//const retVal = this.#events[eventName].callback(payload.requestPayload.args, payload, options, this.#events[eventName].ctx);
|
|
267
|
-
this.#events[eventName].callback(...payload.requestPayload.args, (responseMessage: any) => {
|
|
268
|
-
resolve(responseMessage);
|
|
269
|
-
});
|
|
270
|
-
} catch (error) {
|
|
271
|
-
reject(error);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// p.on('fromworker', (arg1: number, arg2: string, callback: any) => {
|
|
280
|
-
override on(event: string, callback: any, ctx?: any): this {
|
|
281
|
-
if (this.#events[event]) {
|
|
282
|
-
// Update the event with the same name
|
|
283
|
-
delete this.#events[event];
|
|
284
|
-
}
|
|
285
|
-
const eventObject: IEventRecord = {
|
|
286
|
-
event,
|
|
287
|
-
callback,
|
|
288
|
-
ctx
|
|
289
|
-
}
|
|
290
|
-
this.#events[eventObject.event] = eventObject;
|
|
291
|
-
return this;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
override off(event: string, callback?: any): this {
|
|
295
|
-
if (this.#events[event]) {
|
|
296
|
-
delete this.#events[event];
|
|
297
|
-
}
|
|
298
|
-
return this;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
Start = () => {
|
|
302
|
-
this.#ipcMessageManager?.Start();
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
Stop = () => {
|
|
306
|
-
if (this.#pingTimeout) {
|
|
307
|
-
clearTimeout(this.#pingTimeout);
|
|
308
|
-
this.#pingTimeout = null;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
this.#ipcMessageManager?.Stop();
|
|
312
|
-
|
|
313
|
-
this.#redisSubscriber.quit();
|
|
314
|
-
this.#redisSubscriber.disconnect();
|
|
315
|
-
|
|
316
|
-
this.#redisPublisher.quit();
|
|
317
|
-
this.#redisPublisher.disconnect();
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
override emit(event: string, ...args: any[]): this {
|
|
321
|
-
(async () => {
|
|
322
|
-
try {
|
|
323
|
-
const retVal = await this.#ipcMessageManager?.SendMessage({
|
|
324
|
-
__eventName: event,
|
|
325
|
-
args: args.slice(0, args.length-1)
|
|
326
|
-
} as IEventPayload);
|
|
327
|
-
// Invoke the response callback
|
|
328
|
-
args[args.length-1](retVal);
|
|
329
|
-
} catch (error) {
|
|
330
|
-
if (this.#options.ignoreEvents) {
|
|
331
|
-
//console.log(chalk.red(`RedisMessageHandler:emit(): ignoreEvents: [${this.#options.ignoreEvents}]`))
|
|
332
|
-
if (this.#options.ignoreEvents.indexOf((error as any).__eventName) !== -1) {
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
this.#options.logger.error(chalk.red(`RedisMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));
|
|
337
|
-
}
|
|
338
|
-
})();
|
|
339
|
-
return this;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
emitWithError(event: string, args: JSONObject, responseCb: (response: JSONObject | undefined) => void, errorCb: (error: any) => void): this {
|
|
343
|
-
(async () => {
|
|
344
|
-
try {
|
|
345
|
-
const retVal = await this.#ipcMessageManager?.SendMessage({
|
|
346
|
-
__eventName: event,
|
|
347
|
-
args: [ args ]
|
|
348
|
-
} as IEventPayload);
|
|
349
|
-
// Invoke the response callback
|
|
350
|
-
responseCb(retVal);
|
|
351
|
-
} catch (error) {
|
|
352
|
-
if (this.#options.ignoreEvents) {
|
|
353
|
-
//console.log(chalk.red(`RedisMessageHandler:emit(): ignoreEvents: [${this.#options.ignoreEvents}]`))
|
|
354
|
-
if (this.#options.ignoreEvents.indexOf((error as any).__eventName) !== -1) {
|
|
355
|
-
return;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
//this.#options.logger.error(chalk.red(`RedisMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));
|
|
359
|
-
errorCb(error);
|
|
360
|
-
}
|
|
361
|
-
})();
|
|
362
|
-
return this;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
emitex = async(event: string, ...args: any[]): Promise<JSONObject> => {
|
|
366
|
-
return (this.#ipcMessageManager as IPCMessageManager).SendMessage({
|
|
367
|
-
__eventName: event,
|
|
368
|
-
args
|
|
369
|
-
} as IEventPayload);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF
|
|
2
|
-
import { ServiceConfigOptions } from './appConfig'
|
|
3
|
-
import { MasterProcessBase } from './..'
|
|
4
|
-
import { WorkerProcess } from './appWorkerWSS'
|
|
5
|
-
|
|
6
|
-
import cluster, { Worker } from 'node:cluster';
|
|
7
|
-
|
|
8
|
-
import { IPCMessageProcessorWorker } from './../ipcMessageProcessorWorker'
|
|
9
|
-
import { defaultLogger } from '@nsshunt/stsutils';
|
|
10
|
-
|
|
11
|
-
import { IPCMessageProcessorPrimary } from './../ipcMessageProcessorPrimary'
|
|
12
|
-
|
|
13
|
-
import { IIPCMessageProcessorIPCPayload } from './../commonTypes'
|
|
14
|
-
|
|
15
|
-
import chalk from 'chalk';
|
|
16
|
-
|
|
17
|
-
const iterations = 2000;
|
|
18
|
-
|
|
19
|
-
const StartTestPrimary = () => {
|
|
20
|
-
setTimeout(async () => {
|
|
21
|
-
for (const id in cluster.workers) {
|
|
22
|
-
const p1 = new IPCMessageProcessorPrimary({
|
|
23
|
-
logger: defaultLogger,
|
|
24
|
-
namespace: 'test1',
|
|
25
|
-
processPayload: async (payload: IIPCMessageProcessorIPCPayload) => {
|
|
26
|
-
console.log(chalk.grey(`Inside Primary ==> [${process.pid}] Received message from worker: [${JSON.stringify(payload.requestPayload)}]`));
|
|
27
|
-
return {
|
|
28
|
-
msg: `From PRIMARY: [${process.pid}]`,
|
|
29
|
-
yousent: payload.requestPayload,
|
|
30
|
-
hello1: `world1`,
|
|
31
|
-
pid: process.pid
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
p1.Start(cluster.workers[id] as Worker);
|
|
36
|
-
setTimeout(async () => {
|
|
37
|
-
for (let i=0; i < iterations; i++) {
|
|
38
|
-
const sendMessage = {
|
|
39
|
-
from1: `From PRIMARY: [${process.pid}]`,
|
|
40
|
-
loop1: `${i}`,
|
|
41
|
-
};
|
|
42
|
-
console.log(chalk.yellow(`Inside Primary ==> [${process.pid}] Sending message to worker: [${JSON.stringify(sendMessage)}]`));
|
|
43
|
-
const retVal1 = await p1.SendMessage(sendMessage);
|
|
44
|
-
console.log(chalk.yellow(` Inside Primary ==> [${process.pid}] Response from worker: [${JSON.stringify(retVal1)}]`));
|
|
45
|
-
}
|
|
46
|
-
}, 1000);
|
|
47
|
-
}
|
|
48
|
-
}, 2000);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const StartTestWorker = () => {
|
|
52
|
-
setTimeout(() => {
|
|
53
|
-
const w1 = new IPCMessageProcessorWorker({
|
|
54
|
-
logger: defaultLogger,
|
|
55
|
-
namespace: 'test1',
|
|
56
|
-
requestResponseMessageTimeout: 5000,
|
|
57
|
-
processPayload: async (payload) => {
|
|
58
|
-
console.log(chalk.cyan(`Inside Worker ==> [${process.pid}] Received message from primary: [${JSON.stringify(payload.requestPayload)}]`));
|
|
59
|
-
return {
|
|
60
|
-
msg1: `From WORKER: [${process.pid}]`,
|
|
61
|
-
yousent1: payload.requestPayload,
|
|
62
|
-
pid1: process.pid
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
})
|
|
66
|
-
w1.Start();
|
|
67
|
-
setTimeout(async () => {
|
|
68
|
-
for (let i=0; i < iterations; i++) {
|
|
69
|
-
const sendMessage = {
|
|
70
|
-
message:`From WORKER ${process.pid}`,
|
|
71
|
-
loop1: `${i}`,
|
|
72
|
-
};
|
|
73
|
-
console.log(chalk.blue(`Inside Worker ==> [${process.pid}] Sending message to primary: [${JSON.stringify(sendMessage)}]`));
|
|
74
|
-
const retVal1 = await w1.SendMessage(sendMessage);
|
|
75
|
-
console.log(chalk.blue(` Inside Worker ==> [${process.pid}] Response from primary: [${JSON.stringify(retVal1)}]`));
|
|
76
|
-
}
|
|
77
|
-
}, 1000);
|
|
78
|
-
}, 2000);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (cluster.isPrimary) {
|
|
82
|
-
new MasterProcessBase(ServiceConfigOptions(true, cluster.isPrimary)).SetupServer();
|
|
83
|
-
StartTestPrimary();
|
|
84
|
-
} else {
|
|
85
|
-
new WorkerProcess(ServiceConfigOptions(true, cluster.isPrimary)).SetupServer();
|
|
86
|
-
StartTestWorker();
|
|
87
|
-
}
|
package/src/testing/app_ipcex.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF
|
|
2
|
-
import { ServiceConfigOptions } from './appConfig'
|
|
3
|
-
import { MasterProcessBase } from './../masterprocessbase'
|
|
4
|
-
import { WorkerProcess } from './appWorkerWSS'
|
|
5
|
-
|
|
6
|
-
import cluster, { Worker } from 'node:cluster'
|
|
7
|
-
|
|
8
|
-
import { JSONObject, defaultLogger } from '@nsshunt/stsutils';
|
|
9
|
-
|
|
10
|
-
import chalk from 'chalk';
|
|
11
|
-
|
|
12
|
-
import { IPCMessageHandler } from './../ipcMessageHandler'
|
|
13
|
-
|
|
14
|
-
const iterations = 2000;
|
|
15
|
-
|
|
16
|
-
if (cluster.isPrimary) {
|
|
17
|
-
new MasterProcessBase(ServiceConfigOptions(true, cluster.isPrimary)).SetupServer();
|
|
18
|
-
setTimeout(() => {
|
|
19
|
-
const p: Record<string, IPCMessageHandler> = { };
|
|
20
|
-
for (const id in cluster.workers) {
|
|
21
|
-
const worker = cluster.workers[id] as Worker;
|
|
22
|
-
const p1: IPCMessageHandler = new IPCMessageHandler({
|
|
23
|
-
logger: defaultLogger,
|
|
24
|
-
requestResponseMessageTimeout: 5000,
|
|
25
|
-
namespace: 'aabbcc'
|
|
26
|
-
});
|
|
27
|
-
p1.Start(worker);
|
|
28
|
-
p1.on('fromworker', (args: string, pid: number, iterations: number, cb: any) => {
|
|
29
|
-
console.log(chalk.green(`inside primary: ${process.pid}: fromworker event handler: [${args},${pid},${iterations}]`));
|
|
30
|
-
cb(`response from primary - ${pid} ${iterations}`);
|
|
31
|
-
});
|
|
32
|
-
p[worker.id] = p1;
|
|
33
|
-
}
|
|
34
|
-
setTimeout(() => {
|
|
35
|
-
for (let i=0; i < iterations; i++) {
|
|
36
|
-
for (const [workerId, mh] of Object.entries(p)) {
|
|
37
|
-
mh.emit('fromprimary', { hello: "World", id: workerId, iterations: i }, (params: any) => {
|
|
38
|
-
console.log(chalk.cyan(`inside primary: ${process.pid}: fromprimary emit response: [${JSON.stringify(params)}]`));
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}, 1000);
|
|
43
|
-
}, 2000);
|
|
44
|
-
} else {
|
|
45
|
-
new WorkerProcess(ServiceConfigOptions(true, cluster.isPrimary)).SetupServer();
|
|
46
|
-
setTimeout(async () => {
|
|
47
|
-
const w1: IPCMessageHandler = new IPCMessageHandler({
|
|
48
|
-
logger: defaultLogger,
|
|
49
|
-
requestResponseMessageTimeout: 5000,
|
|
50
|
-
namespace: 'aabbcc'
|
|
51
|
-
});
|
|
52
|
-
w1.Start();
|
|
53
|
-
w1.on('fromprimary', (args: JSONObject, cb: any) => {
|
|
54
|
-
console.log(chalk.yellow(`inside worker: ${process.pid}: fromprimary event handler: [${JSON.stringify(args)}]`));
|
|
55
|
-
cb({
|
|
56
|
-
txt: 'response fromprimary',
|
|
57
|
-
args
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
setTimeout(() => {
|
|
61
|
-
for (let i=0; i < iterations; i++) {
|
|
62
|
-
w1.emit('fromworker', "hello", process.pid, i, (args: any) => {
|
|
63
|
-
console.log(chalk.grey(`inside worker: ${process.pid}: fromworker emit response: [${args}]`));
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
}, 1000);
|
|
67
|
-
}, 2000);
|
|
68
|
-
}
|
package/src/testing/app_ww.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF
|
|
2
|
-
import { ServiceConfigOptions } from './appConfig'
|
|
3
|
-
import { MasterProcessBase } from './..'
|
|
4
|
-
import { WorkerProcess } from './appWorkerWSS'
|
|
5
|
-
|
|
6
|
-
import cluster from 'node:cluster';
|
|
7
|
-
|
|
8
|
-
import { JSONObject, defaultLogger } from '@nsshunt/stsutils';
|
|
9
|
-
|
|
10
|
-
import chalk from 'chalk';
|
|
11
|
-
|
|
12
|
-
import { IPCMessageHandler } from './../ipcMessageHandler'
|
|
13
|
-
|
|
14
|
-
import { RedisMessageHandler } from './../redisMessageHandler'
|
|
15
|
-
|
|
16
|
-
import { goptions } from '@nsshunt/stsconfig'
|
|
17
|
-
|
|
18
|
-
import { WebWorkerMessageHandler } from '../messagehandling/webWorkerMessageHandler'
|
|
19
|
-
|
|
20
|
-
import { Worker, MessagePort } from 'worker_threads';
|
|
21
|
-
|
|
22
|
-
import isNode from 'detect-node'
|
|
23
|
-
|
|
24
|
-
if (cluster.isPrimary) {
|
|
25
|
-
|
|
26
|
-
new MasterProcessBase(ServiceConfigOptions(true, cluster.isPrimary)).SetupServer();
|
|
27
|
-
|
|
28
|
-
} else {
|
|
29
|
-
const worker = new WorkerProcess(ServiceConfigOptions(true, cluster.isPrimary));
|
|
30
|
-
worker.SetupServer();
|
|
31
|
-
|
|
32
|
-
setTimeout(async () => {
|
|
33
|
-
const fileName ='./dist/MessageHandling/webWorkerSupport.js';
|
|
34
|
-
const webWorker = new Worker(fileName);
|
|
35
|
-
if (isNode) {
|
|
36
|
-
webWorker.unref();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const wwServer: WebWorkerMessageHandler = new WebWorkerMessageHandler({
|
|
40
|
-
logger: defaultLogger,
|
|
41
|
-
role: 'SERVER',
|
|
42
|
-
namespace: 'mytestapp',
|
|
43
|
-
groups: [ ],
|
|
44
|
-
messagePort: webWorker as any
|
|
45
|
-
});
|
|
46
|
-
wwServer.Start();
|
|
47
|
-
|
|
48
|
-
wwServer.on('test', (arg1: JSONObject, callback: any) => {
|
|
49
|
-
callback( {
|
|
50
|
-
status: `PID: [${process.pid}]: response message from event = fromprimaryredis with args ${JSON.stringify(arg1)}`
|
|
51
|
-
})
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
wwServer.on('globalmessage', (arg1: JSONObject, callback: any) => {
|
|
55
|
-
callback( {
|
|
56
|
-
status: `PID: [${process.pid}]: response message from event = globalmessage with args ${JSON.stringify(arg1)}`
|
|
57
|
-
})
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
setTimeout(async () => {
|
|
61
|
-
const sendObj = { from: 'parent' };
|
|
62
|
-
console.log(chalk.cyan(`calling test = [${JSON.stringify(sendObj)}]`));
|
|
63
|
-
const retVal = await wwServer.emitex('test', sendObj);
|
|
64
|
-
console.log(chalk.cyan(`caller response from test = [${JSON.stringify(retVal)}]`));
|
|
65
|
-
}, 2000);
|
|
66
|
-
|
|
67
|
-
}, 2000);
|
|
68
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { TinyEmitter } from "tiny-emitter";
|
|
2
|
-
import { Worker } from 'node:cluster';
|
|
3
|
-
import { ISTSLogger, JSONObject } from '@nsshunt/stsutils';
|
|
4
|
-
export interface IPCMessageHandlerOptions {
|
|
5
|
-
logger: ISTSLogger;
|
|
6
|
-
requestResponseMessageTimeout: number;
|
|
7
|
-
namespace: string;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* IPC Message Handling.
|
|
11
|
-
*
|
|
12
|
-
* This class can be used to support messages between cluster.primary and cluster.worker instances using IPC.
|
|
13
|
-
* This class can be used for both tghe cluster primary and the cluster worker.
|
|
14
|
-
* Note: Currently groups handling is not supported. Use the redis version for this capability.
|
|
15
|
-
*/
|
|
16
|
-
export declare class IPCMessageHandler extends TinyEmitter {
|
|
17
|
-
#private;
|
|
18
|
-
constructor(options: IPCMessageHandlerOptions);
|
|
19
|
-
get __events(): JSONObject;
|
|
20
|
-
SetupPrimary: () => void;
|
|
21
|
-
SetupWorker: () => void;
|
|
22
|
-
SendMessage: (payload: JSONObject) => Promise<JSONObject>;
|
|
23
|
-
on(event: string, callback: any, ctx?: any): this;
|
|
24
|
-
off(event: string, callback?: any): this;
|
|
25
|
-
Start: (worker?: Worker) => void;
|
|
26
|
-
Stop: () => void;
|
|
27
|
-
get worker(): Worker | null;
|
|
28
|
-
emit(event: string, ...args: any[]): this;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=ipcMessageHandler.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
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;CACpB;AAED;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,WAAW;;gBAQlC,OAAO,EAAE,wBAAwB;IAU7C,IAAI,QAAQ,eAEX;IAMD,YAAY,aAyBX;IAMD,WAAW,aAyBV;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,30 +0,0 @@
|
|
|
1
|
-
import { ISTSLogger, JSONObject } from '@nsshunt/stsutils';
|
|
2
|
-
import { IIPCMessageProcessorIPCPayload } from './commonTypes';
|
|
3
|
-
export interface IPCMessageManagerOptions {
|
|
4
|
-
logger: ISTSLogger;
|
|
5
|
-
requestResponseMessageTimeout: number;
|
|
6
|
-
namespace: string;
|
|
7
|
-
role: 'SERVER' | 'CLIENT';
|
|
8
|
-
groups: string[];
|
|
9
|
-
messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => void;
|
|
10
|
-
ProcessRequestMessage: (payload: IIPCMessageProcessorIPCPayload, options: any) => Promise<JSONObject>;
|
|
11
|
-
ProcessResponseMessage?: (reesponses: Record<string, IIPCMessageProcessorIPCPayload>, options: any) => Promise<boolean>;
|
|
12
|
-
messageReceiverStart: (options: any) => void;
|
|
13
|
-
messageReceiverStop: (options: any) => void;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* todo
|
|
17
|
-
* @typedef {Object} options - todo
|
|
18
|
-
* @property {boolean} [wssServer=false] - Create a web socket server on this worker instance
|
|
19
|
-
*/
|
|
20
|
-
export declare class IPCMessageManager {
|
|
21
|
-
#private;
|
|
22
|
-
constructor(options: IPCMessageManagerOptions);
|
|
23
|
-
get id(): string;
|
|
24
|
-
ReceivedMessageFromMaster(msg: any): void;
|
|
25
|
-
SendMessage: (payload: JSONObject, options?: any) => Promise<JSONObject>;
|
|
26
|
-
Start: (options?: any) => void;
|
|
27
|
-
Stop: (options?: any) => void;
|
|
28
|
-
ProcessMessage: (msg: any, options: any) => Promise<void>;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=ipcMessageManager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ipcMessageManager.d.ts","sourceRoot":"","sources":["../src/ipcMessageManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAI1D,OAAO,EAAE,8BAA8B,EAAoC,MAAM,eAAe,CAAA;AAEhG,MAAM,WAAW,wBAAwB;IACrC,MAAM,EAAE,UAAU,CAAA;IAClB,6BAA6B,EAAE,MAAM,CAAA;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAA;IACzB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,aAAa,EAAE,CAAC,OAAO,EAAE,8BAA8B,EAAE,OAAO,EAAE,GAAG,KAAK,IAAI,CAAA;IAC9E,qBAAqB,EAAE,CAAC,OAAO,EAAE,8BAA8B,EAAE,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;IACrG,sBAAsB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,8BAA8B,CAAC,EAAE,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACvH,oBAAoB,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAA;IAC5C,mBAAmB,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAA;CAC9C;AACD;;;;GAIG;AACH,qBAAa,iBAAiB;;gBAOd,OAAO,EAAE,wBAAwB;IAM7C,IAAI,EAAE,WAEL;IAGD,yBAAyB,CAAC,GAAG,EAAE,GAAG;IAIlC,WAAW,YAAa,UAAU,YAAY,GAAG,KAAG,OAAO,CAAC,UAAU,CAAC,CAUtE;IAwED,KAAK,aAAc,GAAG,UAGrB;IAED,IAAI,aAAc,GAAG,UAUpB;IAGD,cAAc,QAAe,GAAG,WAAW,GAAG,mBAuB7C;CACJ"}
|