@nsshunt/stsappframework 3.1.178 → 3.1.179
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/dist/MessageHandling/webWorkerMessageHandler.js +280 -0
- package/dist/MessageHandling/webWorkerMessageHandler.js.map +1 -0
- package/dist/MessageHandling/webWorkerSupport.js +62 -0
- package/dist/MessageHandling/webWorkerSupport.js.map +1 -0
- package/dist/testing/app_ww.js +54 -0
- package/dist/testing/app_ww.js.map +1 -0
- package/package.json +1 -1
- package/runtest_ww.sh +19 -0
- package/src/MessageHandling/webWorkerMessageHandler.ts +341 -0
- package/src/MessageHandling/webWorkerSupport.ts +66 -0
- package/src/testing/app_ww.ts +68 -0
- package/types/MessageHandling/webWorkerMessageHandler.d.ts +52 -0
- package/types/MessageHandling/webWorkerMessageHandler.d.ts.map +1 -0
- package/types/MessageHandling/webWorkerSupport.d.ts +6 -0
- package/types/MessageHandling/webWorkerSupport.d.ts.map +1 -0
- package/types/testing/app_ww.d.ts +2 -0
- package/types/testing/app_ww.d.ts.map +1 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.WebWorkerMessageHandler = void 0;
|
|
7
|
+
/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF */ // --> OFF
|
|
8
|
+
const tiny_emitter_1 = require("tiny-emitter");
|
|
9
|
+
const ipcMessageManager_1 = require("./../ipcMessageManager");
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
+
class WebWorkerMessageHandler extends tiny_emitter_1.TinyEmitter {
|
|
12
|
+
#ipcMessageManager = null;
|
|
13
|
+
#options;
|
|
14
|
+
#events = {};
|
|
15
|
+
#clients = {};
|
|
16
|
+
#pingTimeout = null;
|
|
17
|
+
#messagePort;
|
|
18
|
+
constructor(options) {
|
|
19
|
+
super();
|
|
20
|
+
this.#options = options;
|
|
21
|
+
this.#messagePort = options.messagePort;
|
|
22
|
+
this.SetupPrimary();
|
|
23
|
+
if (this.#options.role.localeCompare('CLIENT') === 0) {
|
|
24
|
+
const ping = () => {
|
|
25
|
+
this.#pingTimeout = setTimeout(() => {
|
|
26
|
+
const pingData = {
|
|
27
|
+
id: this.#ipcMessageManager.id,
|
|
28
|
+
groups: this.#options.groups,
|
|
29
|
+
};
|
|
30
|
+
if (this.#options.processOptions) {
|
|
31
|
+
pingData.serviceProcessContext = this.#options.processOptions.serviceProcessContext;
|
|
32
|
+
}
|
|
33
|
+
this.emit('ping', pingData, (response) => { });
|
|
34
|
+
ping();
|
|
35
|
+
}, 1000).unref();
|
|
36
|
+
};
|
|
37
|
+
ping();
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
this.on('ping', (pingData, callback) => {
|
|
41
|
+
const { id, groups, serviceProcessContext } = pingData;
|
|
42
|
+
if (this.#clients[id]) {
|
|
43
|
+
clearTimeout(this.#clients[id].timeout);
|
|
44
|
+
this.#clients[id].pingCount++;
|
|
45
|
+
this.#clients[id].timeout = setTimeout(() => {
|
|
46
|
+
delete this.#clients[id];
|
|
47
|
+
}, 2000);
|
|
48
|
+
this.#clients[id].groups = groups;
|
|
49
|
+
this.#clients[id].serviceProcessContext = serviceProcessContext;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
this.#clients[id] = {
|
|
53
|
+
id,
|
|
54
|
+
clientConnected: new Date(),
|
|
55
|
+
pingCount: 0,
|
|
56
|
+
timeout: setTimeout(() => {
|
|
57
|
+
delete this.#clients[id];
|
|
58
|
+
}, 2000),
|
|
59
|
+
groups,
|
|
60
|
+
serviceProcessContext
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
callback('ok');
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
#processRawMessage = (rawmessage) => {
|
|
68
|
+
const message = JSON.parse(rawmessage);
|
|
69
|
+
this.#ipcMessageManager?.ProcessMessage(message, {});
|
|
70
|
+
};
|
|
71
|
+
get clients() {
|
|
72
|
+
return this.#clients;
|
|
73
|
+
}
|
|
74
|
+
get groups() {
|
|
75
|
+
return this.#options.groups;
|
|
76
|
+
}
|
|
77
|
+
AddGroup = (group) => {
|
|
78
|
+
const index = this.#options.groups.indexOf(group);
|
|
79
|
+
if (index === -1) {
|
|
80
|
+
this.#options.groups.push(group);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
RemoveGroup = (group) => {
|
|
84
|
+
const removeIndex = this.#options.groups.indexOf(group);
|
|
85
|
+
if (removeIndex !== -1) {
|
|
86
|
+
this.#options.groups.splice(removeIndex, 1);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
SetupPrimary = () => {
|
|
90
|
+
const ipcMessageManagerOptions = {
|
|
91
|
+
logger: this.#options.logger,
|
|
92
|
+
requestResponseMessageTimeout: 5000,
|
|
93
|
+
namespace: this.#options.namespace,
|
|
94
|
+
role: this.#options.role,
|
|
95
|
+
messageSender: this.#messageSender,
|
|
96
|
+
groups: this.#options.groups,
|
|
97
|
+
// This method is used to calculate if all responses have been received from multiple clients (broadcast)
|
|
98
|
+
// returns true/false.
|
|
99
|
+
ProcessResponseMessage: this.#ProcessResponseMessage,
|
|
100
|
+
// This gets called when an event is received from a message receiver (when ProcessMessage is invoked from the receiver event handler)
|
|
101
|
+
ProcessRequestMessage: this.#processPayload,
|
|
102
|
+
messageReceiverStart: (options) => {
|
|
103
|
+
this.#messagePort.on('message', this.#processRawMessage);
|
|
104
|
+
//this.#redisSubscriber.on("message", this.#processRawMessage);
|
|
105
|
+
},
|
|
106
|
+
messageReceiverStop: (options) => {
|
|
107
|
+
this.#messagePort.off("message", this.#processRawMessage);
|
|
108
|
+
//this.#redisSubscriber.off("message", this.#processRawMessage);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
this.#ipcMessageManager = new ipcMessageManager_1.IPCMessageManager(ipcMessageManagerOptions);
|
|
112
|
+
};
|
|
113
|
+
#messageSender = (payload, options) => {
|
|
114
|
+
if (payload.messageType.localeCompare('REQUEST') === 0) {
|
|
115
|
+
//this.#redisPublisher.publish(this.#requestChannel, JSON.stringify(payload));
|
|
116
|
+
this.#messagePort.postMessage(JSON.stringify(payload));
|
|
117
|
+
}
|
|
118
|
+
else if (payload.messageType.localeCompare('RESPONSE') === 0) {
|
|
119
|
+
this.#messagePort.postMessage(JSON.stringify(payload));
|
|
120
|
+
//this.#redisPublisher.publish(this.#responseChannel, JSON.stringify(payload));
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
#ProcessResponseMessage = async (responses, options) => {
|
|
124
|
+
// Now check if we have all responses ...
|
|
125
|
+
let allFound = false;
|
|
126
|
+
for (const [responseId, response] of Object.entries(responses)) {
|
|
127
|
+
if (response.senderRole.localeCompare('CLIENT') === 0) {
|
|
128
|
+
allFound = true;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (allFound) {
|
|
133
|
+
return allFound;
|
|
134
|
+
}
|
|
135
|
+
let found = true;
|
|
136
|
+
// Sender role here is SERVER
|
|
137
|
+
let requestGroup = null;
|
|
138
|
+
for (const [responseId, response] of Object.entries(responses)) {
|
|
139
|
+
if (response.requestPayload.args.length > 0 && response.requestPayload.args[0].group) {
|
|
140
|
+
requestGroup = response.requestPayload.args[0].group;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (requestGroup) {
|
|
145
|
+
const clientsInGroup = Object.values(this.#clients).filter(c => {
|
|
146
|
+
if (c.groups.indexOf(requestGroup) === -1) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
return true;
|
|
150
|
+
});
|
|
151
|
+
// Now make sure that all clients are in the responses
|
|
152
|
+
found = true;
|
|
153
|
+
clientsInGroup.forEach(c => {
|
|
154
|
+
if (!responses[c.id]) {
|
|
155
|
+
found = false;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
const clientsInGroup = Object.values(this.#clients);
|
|
161
|
+
// Now make sure that all clients are in the responses
|
|
162
|
+
found = true;
|
|
163
|
+
clientsInGroup.forEach(c => {
|
|
164
|
+
if (!responses[c.id]) {
|
|
165
|
+
found = false;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return found;
|
|
170
|
+
};
|
|
171
|
+
#processPayload = (payload, options) => {
|
|
172
|
+
// check the event name from the collection and invoke that function
|
|
173
|
+
return new Promise((resolve, reject) => {
|
|
174
|
+
if (payload.messageType.localeCompare('REQUEST') === 0) {
|
|
175
|
+
if (payload.requestPayload['__eventName']) {
|
|
176
|
+
const eventName = payload.requestPayload['__eventName'];
|
|
177
|
+
// Only process events that I have registered interest in (using .on)
|
|
178
|
+
if (this.#events[eventName]) {
|
|
179
|
+
try {
|
|
180
|
+
//const retVal = this.#events[eventName].callback(payload.requestPayload.args, payload, options, this.#events[eventName].ctx);
|
|
181
|
+
this.#events[eventName].callback(...payload.requestPayload.args, (responseMessage) => {
|
|
182
|
+
resolve(responseMessage);
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
reject(error);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
// p.on('fromworker', (arg1: number, arg2: string, callback: any) => {
|
|
194
|
+
on(event, callback, ctx) {
|
|
195
|
+
if (this.#events[event]) {
|
|
196
|
+
// Update the event with the same name
|
|
197
|
+
delete this.#events[event];
|
|
198
|
+
}
|
|
199
|
+
const eventObject = {
|
|
200
|
+
event,
|
|
201
|
+
callback,
|
|
202
|
+
ctx
|
|
203
|
+
};
|
|
204
|
+
this.#events[eventObject.event] = eventObject;
|
|
205
|
+
return this;
|
|
206
|
+
}
|
|
207
|
+
off(event, callback) {
|
|
208
|
+
if (this.#events[event]) {
|
|
209
|
+
delete this.#events[event];
|
|
210
|
+
}
|
|
211
|
+
return this;
|
|
212
|
+
}
|
|
213
|
+
Start = () => {
|
|
214
|
+
this.#ipcMessageManager?.Start();
|
|
215
|
+
};
|
|
216
|
+
Stop = () => {
|
|
217
|
+
if (this.#pingTimeout) {
|
|
218
|
+
clearTimeout(this.#pingTimeout);
|
|
219
|
+
this.#pingTimeout = null;
|
|
220
|
+
}
|
|
221
|
+
this.#ipcMessageManager?.Stop();
|
|
222
|
+
/*
|
|
223
|
+
this.#redisSubscriber.quit();
|
|
224
|
+
this.#redisSubscriber.disconnect();
|
|
225
|
+
|
|
226
|
+
this.#redisPublisher.quit();
|
|
227
|
+
this.#redisPublisher.disconnect();
|
|
228
|
+
*/
|
|
229
|
+
};
|
|
230
|
+
emit(event, ...args) {
|
|
231
|
+
(async () => {
|
|
232
|
+
try {
|
|
233
|
+
const retVal = await this.#ipcMessageManager?.SendMessage({
|
|
234
|
+
__eventName: event,
|
|
235
|
+
args: args.slice(0, args.length - 1)
|
|
236
|
+
});
|
|
237
|
+
// Invoke the response callback
|
|
238
|
+
args[args.length - 1](retVal);
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
if (this.#options.ignoreEvents) {
|
|
242
|
+
if (this.#options.ignoreEvents.indexOf(error.__eventName) !== -1) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
this.#options.logger.error(chalk_1.default.red(`RedisMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));
|
|
247
|
+
}
|
|
248
|
+
})();
|
|
249
|
+
return this;
|
|
250
|
+
}
|
|
251
|
+
emitWithError(event, args, responseCb, errorCb) {
|
|
252
|
+
(async () => {
|
|
253
|
+
try {
|
|
254
|
+
const retVal = await this.#ipcMessageManager?.SendMessage({
|
|
255
|
+
__eventName: event,
|
|
256
|
+
args: [args]
|
|
257
|
+
});
|
|
258
|
+
// Invoke the response callback
|
|
259
|
+
responseCb(retVal);
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
if (this.#options.ignoreEvents) {
|
|
263
|
+
if (this.#options.ignoreEvents.indexOf(error.__eventName) !== -1) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
errorCb(error);
|
|
268
|
+
}
|
|
269
|
+
})();
|
|
270
|
+
return this;
|
|
271
|
+
}
|
|
272
|
+
emitex = async (event, ...args) => {
|
|
273
|
+
return this.#ipcMessageManager.SendMessage({
|
|
274
|
+
__eventName: event,
|
|
275
|
+
args
|
|
276
|
+
});
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
exports.WebWorkerMessageHandler = WebWorkerMessageHandler;
|
|
280
|
+
//# sourceMappingURL=webWorkerMessageHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webWorkerMessageHandler.js","sourceRoot":"","sources":["../../src/MessageHandling/webWorkerMessageHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.WorkerSupport = void 0;
|
|
7
|
+
/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF */ // --> OFF
|
|
8
|
+
const worker_threads_1 = require("worker_threads");
|
|
9
|
+
const webWorkerMessageHandler_1 = require("./webWorkerMessageHandler");
|
|
10
|
+
const stsutils_1 = require("@nsshunt/stsutils");
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
class WorkerSupport {
|
|
13
|
+
#wwClient = null;
|
|
14
|
+
constructor() {
|
|
15
|
+
this.#wwClient = new webWorkerMessageHandler_1.WebWorkerMessageHandler({
|
|
16
|
+
logger: stsutils_1.defaultLogger,
|
|
17
|
+
role: 'CLIENT',
|
|
18
|
+
namespace: 'mytestapp',
|
|
19
|
+
groups: [],
|
|
20
|
+
ignoreEvents: ['ping'],
|
|
21
|
+
messagePort: worker_threads_1.parentPort
|
|
22
|
+
});
|
|
23
|
+
this.#wwClient.Start();
|
|
24
|
+
this.#wwClient.on('test', (arg1, callback) => {
|
|
25
|
+
callback({
|
|
26
|
+
status: `PID: [${process.pid}]: response message from event = test with args ${JSON.stringify(arg1)}`
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
this.#wwClient.on('globalmessage', (arg1, callback) => {
|
|
30
|
+
callback({
|
|
31
|
+
status: `PID: [${process.pid}]: response message from event = globalmessage with args ${JSON.stringify(arg1)}`
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
setTimeout(async () => {
|
|
35
|
+
const sendObj1 = { from: 'child1' };
|
|
36
|
+
console.log(chalk_1.default.magenta(`calling globalmessage = [${JSON.stringify(sendObj1)}]`));
|
|
37
|
+
const retVal1 = await this.#wwClient?.emitex('globalmessage', sendObj1);
|
|
38
|
+
console.log(chalk_1.default.magenta(`caller response from globalmessage = [${JSON.stringify(retVal1)}]`));
|
|
39
|
+
const sendObj2 = { from: 'child2' };
|
|
40
|
+
console.log(chalk_1.default.magenta(`calling test = [${JSON.stringify(sendObj2)}]`));
|
|
41
|
+
const retVal2 = await this.#wwClient?.emitex('test', sendObj2);
|
|
42
|
+
console.log(chalk_1.default.magenta(`caller response from test = [${JSON.stringify(retVal2)}]`));
|
|
43
|
+
}, 2000);
|
|
44
|
+
}
|
|
45
|
+
ProcessMessage = async (data) => {
|
|
46
|
+
console.log(`Received: [${data}]`);
|
|
47
|
+
//parentPort?.postMessage(data);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
exports.WorkerSupport = WorkerSupport;
|
|
51
|
+
new WorkerSupport();
|
|
52
|
+
/*
|
|
53
|
+
parentPort?.on('message', (data: any) => {
|
|
54
|
+
if (isNode) {
|
|
55
|
+
worker.ProcessMessage(data);
|
|
56
|
+
} else {
|
|
57
|
+
// const payloadMessage: IIWMessagePayload = data.data as IIWMessagePayload; // browser version
|
|
58
|
+
worker.ProcessMessage(data.data); // browser version
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
*/
|
|
62
|
+
//# sourceMappingURL=webWorkerSupport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webWorkerSupport.js","sourceRoot":"","sources":["../../src/MessageHandling/webWorkerSupport.ts"],"names":[],"mappings":";;;;;;AAAA,wFAAwF,CAAE,yBAAyB;AACnH,mDAAyD;AAEzD,uEAAmE;AAEnE,gDAA6D;AAE7D,kDAA0B;AAE1B,MAAa,aAAa;IACtB,SAAS,GAAmC,IAAI,CAAC;IAEjD;QACI,IAAI,CAAC,SAAS,GAAG,IAAI,iDAAuB,CAAC;YACzC,MAAM,EAAE,wBAAa;YACrB,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,WAAW;YACtB,MAAM,EAAE,EAAG;YACX,YAAY,EAAE,CAAE,MAAM,CAAE;YACxB,WAAW,EAAE,2BAAyB;SACzC,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QAEvB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAgB,EAAE,QAAa,EAAE,EAAE;YAC1D,QAAQ,CAAE;gBACN,MAAM,EAAE,SAAS,OAAO,CAAC,GAAG,mDAAmD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;aACxG,CAAC,CAAA;QACN,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,IAAgB,EAAE,QAAa,EAAE,EAAE;YACnE,QAAQ,CAAE;gBACN,MAAM,EAAE,SAAS,OAAO,CAAC,GAAG,4DAA4D,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;aACjH,CAAC,CAAA;QACN,CAAC,CAAC,CAAC;QAEH,UAAU,CAAC,KAAK,IAAI,EAAE;YAClB,MAAM,QAAQ,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,OAAO,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YACpF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;YACxE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,OAAO,CAAC,yCAAyC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YAEhG,MAAM,QAAQ,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,OAAO,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3E,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC/D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,OAAO,CAAC,gCAAgC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3F,CAAC,EAAE,IAAI,CAAC,CAAC;IACb,CAAC;IAED,cAAc,GAAG,KAAK,EAAC,IAAS,EAAE,EAAE;QAChC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC,CAAC;QACnC,gCAAgC;IACpC,CAAC,CAAA;CACJ;AA3CD,sCA2CC;AAED,IAAI,aAAa,EAAE,CAAC;AAEpB;;;;;;;;;EASE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF
|
|
7
|
+
const appConfig_1 = require("./appConfig");
|
|
8
|
+
const __1 = require("./..");
|
|
9
|
+
const appWorkerWSS_1 = require("./appWorkerWSS");
|
|
10
|
+
const node_cluster_1 = __importDefault(require("node:cluster"));
|
|
11
|
+
const stsutils_1 = require("@nsshunt/stsutils");
|
|
12
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
13
|
+
const webWorkerMessageHandler_1 = require("./../MessageHandling/webWorkerMessageHandler");
|
|
14
|
+
const worker_threads_1 = require("worker_threads");
|
|
15
|
+
const detect_node_1 = __importDefault(require("detect-node"));
|
|
16
|
+
if (node_cluster_1.default.isPrimary) {
|
|
17
|
+
new __1.MasterProcessBase((0, appConfig_1.ServiceConfigOptions)(true, node_cluster_1.default.isPrimary)).SetupServer();
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
const worker = new appWorkerWSS_1.WorkerProcess((0, appConfig_1.ServiceConfigOptions)(true, node_cluster_1.default.isPrimary));
|
|
21
|
+
worker.SetupServer();
|
|
22
|
+
setTimeout(async () => {
|
|
23
|
+
const fileName = './dist/MessageHandling/webWorkerSupport.js';
|
|
24
|
+
const webWorker = new worker_threads_1.Worker(fileName);
|
|
25
|
+
if (detect_node_1.default) {
|
|
26
|
+
webWorker.unref();
|
|
27
|
+
}
|
|
28
|
+
const wwServer = new webWorkerMessageHandler_1.WebWorkerMessageHandler({
|
|
29
|
+
logger: stsutils_1.defaultLogger,
|
|
30
|
+
role: 'SERVER',
|
|
31
|
+
namespace: 'mytestapp',
|
|
32
|
+
groups: [],
|
|
33
|
+
messagePort: webWorker
|
|
34
|
+
});
|
|
35
|
+
wwServer.Start();
|
|
36
|
+
wwServer.on('test', (arg1, callback) => {
|
|
37
|
+
callback({
|
|
38
|
+
status: `PID: [${process.pid}]: response message from event = fromprimaryredis with args ${JSON.stringify(arg1)}`
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
wwServer.on('globalmessage', (arg1, callback) => {
|
|
42
|
+
callback({
|
|
43
|
+
status: `PID: [${process.pid}]: response message from event = globalmessage with args ${JSON.stringify(arg1)}`
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
setTimeout(async () => {
|
|
47
|
+
const sendObj = { from: 'parent' };
|
|
48
|
+
console.log(chalk_1.default.cyan(`calling test = [${JSON.stringify(sendObj)}]`));
|
|
49
|
+
const retVal = await wwServer.emitex('test', sendObj);
|
|
50
|
+
console.log(chalk_1.default.cyan(`caller response from test = [${JSON.stringify(retVal)}]`));
|
|
51
|
+
}, 2000);
|
|
52
|
+
}, 2000);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=app_ww.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app_ww.js","sourceRoot":"","sources":["../../src/testing/app_ww.ts"],"names":[],"mappings":";;;;;AAAA,wFAAwF,CAAE,UAAU;AACpG,2CAAkD;AAClD,4BAAwC;AACxC,iDAA8C;AAE9C,gEAAmC;AAEnC,gDAA8D;AAE9D,kDAA0B;AAQ1B,0FAAsF;AAEtF,mDAAqD;AAErD,8DAAgC;AAEhC,IAAI,sBAAO,CAAC,SAAS,EAAE,CAAC;IAEpB,IAAI,qBAAiB,CAAC,IAAA,gCAAoB,EAAC,IAAI,EAAE,sBAAO,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AAEvF,CAAC;KAAM,CAAC;IACJ,MAAM,MAAM,GAAG,IAAI,4BAAa,CAAC,IAAA,gCAAoB,EAAC,IAAI,EAAE,sBAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAChF,MAAM,CAAC,WAAW,EAAE,CAAC;IAErB,UAAU,CAAC,KAAK,IAAI,EAAE;QAClB,MAAM,QAAQ,GAAE,4CAA4C,CAAC;QAC7D,MAAM,SAAS,GAAG,IAAI,uBAAM,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,qBAAM,EAAE,CAAC;YACT,SAAS,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC;QAED,MAAM,QAAQ,GAA4B,IAAI,iDAAuB,CAAC;YAClE,MAAM,EAAE,wBAAa;YACrB,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,WAAW;YACtB,MAAM,EAAE,EAAG;YACX,WAAW,EAAE,SAAgB;SAChC,CAAC,CAAC;QACH,QAAQ,CAAC,KAAK,EAAE,CAAC;QAEjB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAgB,EAAE,QAAa,EAAE,EAAE;YACpD,QAAQ,CAAE;gBACN,MAAM,EAAE,SAAS,OAAO,CAAC,GAAG,+DAA+D,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;aACpH,CAAC,CAAA;QACN,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,IAAgB,EAAE,QAAa,EAAE,EAAE;YAC7D,QAAQ,CAAE;gBACN,MAAM,EAAE,SAAS,OAAO,CAAC,GAAG,4DAA4D,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;aACjH,CAAC,CAAA;QACN,CAAC,CAAC,CAAC;QAEH,UAAU,CAAC,KAAK,IAAI,EAAE;YAClB,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YACvE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,gCAAgC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACvF,CAAC,EAAE,IAAI,CAAC,CAAC;IAEb,CAAC,EAAE,IAAI,CAAC,CAAC;AACb,CAAC"}
|
package/package.json
CHANGED
package/runtest_ww.sh
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# openssl req -nodes -new -x509 -keyout server.key -out server.cert
|
|
3
|
+
clear; \
|
|
4
|
+
export STS_PROJ_ROOT=./..; \
|
|
5
|
+
STSENVFILE=$STS_PROJ_ROOT/stsglobalresources/.env \
|
|
6
|
+
REST01_PORT=3003 \
|
|
7
|
+
REST01_HOST_PORT=3003 \
|
|
8
|
+
REST01_ENDPOINT="https://stscore.stsmda.org" \
|
|
9
|
+
MAX_CPU=1 \
|
|
10
|
+
AS_ENDPOINT=https://stscore.stsmda.org \
|
|
11
|
+
AS_HOST_PORT=3002 \
|
|
12
|
+
AS_PORT=3002 \
|
|
13
|
+
DB_HOST=localhost:5432 \
|
|
14
|
+
DB_PASSWORD=postgres \
|
|
15
|
+
HTTPS_SERVER_KEY_PATH=/etc/letsencrypt/live/stsmda.org/privkey.pem \
|
|
16
|
+
HTTPS_SERVER_CERT_PATH=/etc/letsencrypt/live/stsmda.org/fullchain.pem \
|
|
17
|
+
DEBUG=proc* \
|
|
18
|
+
UV_THREADPOOL_SIZE=64 \
|
|
19
|
+
node dist/testing/app_ww
|
|
@@ -0,0 +1,341 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF */ // --> OFF
|
|
2
|
+
import { parentPort, MessagePort } from 'worker_threads';
|
|
3
|
+
|
|
4
|
+
import { WebWorkerMessageHandler } from './webWorkerMessageHandler'
|
|
5
|
+
|
|
6
|
+
import { defaultLogger, JSONObject } from '@nsshunt/stsutils'
|
|
7
|
+
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
|
|
10
|
+
export class WorkerSupport {
|
|
11
|
+
#wwClient: WebWorkerMessageHandler | null = null;
|
|
12
|
+
|
|
13
|
+
constructor() {
|
|
14
|
+
this.#wwClient = new WebWorkerMessageHandler({
|
|
15
|
+
logger: defaultLogger,
|
|
16
|
+
role: 'CLIENT',
|
|
17
|
+
namespace: 'mytestapp',
|
|
18
|
+
groups: [ ],
|
|
19
|
+
ignoreEvents: [ 'ping' ],
|
|
20
|
+
messagePort: parentPort as MessagePort
|
|
21
|
+
});
|
|
22
|
+
this.#wwClient.Start();
|
|
23
|
+
|
|
24
|
+
this.#wwClient.on('test', (arg1: JSONObject, callback: any) => {
|
|
25
|
+
callback( {
|
|
26
|
+
status: `PID: [${process.pid}]: response message from event = test with args ${JSON.stringify(arg1)}`
|
|
27
|
+
})
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
this.#wwClient.on('globalmessage', (arg1: JSONObject, callback: any) => {
|
|
31
|
+
callback( {
|
|
32
|
+
status: `PID: [${process.pid}]: response message from event = globalmessage with args ${JSON.stringify(arg1)}`
|
|
33
|
+
})
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
setTimeout(async () => {
|
|
37
|
+
const sendObj1 = { from: 'child1' };
|
|
38
|
+
console.log(chalk.magenta(`calling globalmessage = [${JSON.stringify(sendObj1)}]`));
|
|
39
|
+
const retVal1 = await this.#wwClient?.emitex('globalmessage', sendObj1);
|
|
40
|
+
console.log(chalk.magenta(`caller response from globalmessage = [${JSON.stringify(retVal1)}]`));
|
|
41
|
+
|
|
42
|
+
const sendObj2 = { from: 'child2' };
|
|
43
|
+
console.log(chalk.magenta(`calling test = [${JSON.stringify(sendObj2)}]`));
|
|
44
|
+
const retVal2 = await this.#wwClient?.emitex('test', sendObj2);
|
|
45
|
+
console.log(chalk.magenta(`caller response from test = [${JSON.stringify(retVal2)}]`));
|
|
46
|
+
}, 2000);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
ProcessMessage = async(data: any) => {
|
|
50
|
+
console.log(`Received: [${data}]`);
|
|
51
|
+
//parentPort?.postMessage(data);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
new WorkerSupport();
|
|
56
|
+
|
|
57
|
+
/*
|
|
58
|
+
parentPort?.on('message', (data: any) => {
|
|
59
|
+
if (isNode) {
|
|
60
|
+
worker.ProcessMessage(data);
|
|
61
|
+
} else {
|
|
62
|
+
// const payloadMessage: IIWMessagePayload = data.data as IIWMessagePayload; // browser version
|
|
63
|
+
worker.ProcessMessage(data.data); // browser version
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
*/
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { TinyEmitter } from "tiny-emitter";
|
|
2
|
+
import { ISTSLogger, JSONObject } from '@nsshunt/stsutils';
|
|
3
|
+
import { IServiceProcessContext, ProcessOptions } from './../commonTypes';
|
|
4
|
+
import { MessagePort } from 'worker_threads';
|
|
5
|
+
export interface IWebWorderMessageHandlerOptions {
|
|
6
|
+
logger: ISTSLogger;
|
|
7
|
+
role: 'SERVER' | 'CLIENT';
|
|
8
|
+
namespace: string;
|
|
9
|
+
groups: string[];
|
|
10
|
+
ignoreEvents?: string[];
|
|
11
|
+
processOptions?: ProcessOptions;
|
|
12
|
+
messagePort: MessagePort;
|
|
13
|
+
}
|
|
14
|
+
export interface IClientRecord {
|
|
15
|
+
id: string;
|
|
16
|
+
clientConnected: Date;
|
|
17
|
+
pingCount: number;
|
|
18
|
+
timeout: NodeJS.Timeout;
|
|
19
|
+
groups: string[];
|
|
20
|
+
serviceProcessContext?: IServiceProcessContext;
|
|
21
|
+
}
|
|
22
|
+
export interface IEventPayload {
|
|
23
|
+
__eventName: string;
|
|
24
|
+
args: any[];
|
|
25
|
+
}
|
|
26
|
+
export interface IEventRecord {
|
|
27
|
+
event: string;
|
|
28
|
+
callback: any;
|
|
29
|
+
ctx?: any;
|
|
30
|
+
}
|
|
31
|
+
export interface IPingData {
|
|
32
|
+
id: string;
|
|
33
|
+
groups: string[];
|
|
34
|
+
serviceProcessContext?: IServiceProcessContext;
|
|
35
|
+
}
|
|
36
|
+
export declare class WebWorkerMessageHandler extends TinyEmitter {
|
|
37
|
+
#private;
|
|
38
|
+
constructor(options: IWebWorderMessageHandlerOptions);
|
|
39
|
+
get clients(): Record<string, IClientRecord>;
|
|
40
|
+
get groups(): string[];
|
|
41
|
+
AddGroup: (group: string) => void;
|
|
42
|
+
RemoveGroup: (group: string) => void;
|
|
43
|
+
SetupPrimary: () => void;
|
|
44
|
+
on(event: string, callback: any, ctx?: any): this;
|
|
45
|
+
off(event: string, callback?: any): this;
|
|
46
|
+
Start: () => void;
|
|
47
|
+
Stop: () => void;
|
|
48
|
+
emit(event: string, ...args: any[]): this;
|
|
49
|
+
emitWithError(event: string, args: JSONObject, responseCb: (response: JSONObject | undefined) => void, errorCb: (error: any) => void): this;
|
|
50
|
+
emitex: (event: string, ...args: any[]) => Promise<JSONObject>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=webWorkerMessageHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webWorkerMessageHandler.d.ts","sourceRoot":"","sources":["../../src/MessageHandling/webWorkerMessageHandler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE1D,OAAO,EAAkC,sBAAsB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAMzG,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,WAAW,+BAA+B;IAC5C,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAA;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,WAAW,EAAE,WAAW,CAAA;CAC3B;AAED,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,eAAe,EAAE,IAAI,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAA;IACvB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,qBAAqB,CAAC,EAAE,sBAAsB,CAAA;CACjD;AAED,MAAM,WAAW,aAAa;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,GAAG,EAAE,CAAA;CACd;AAED,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,GAAG,CAAC;IACd,GAAG,CAAC,EAAE,GAAG,CAAA;CACZ;AAED,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,qBAAqB,CAAC,EAAE,sBAAsB,CAAA;CACjD;AAED,qBAAa,uBAAwB,SAAQ,WAAW;;gBAQxC,OAAO,EAAE,+BAA+B;IAuDpD,IAAI,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAE3C;IAED,IAAI,MAAM,IAAI,MAAM,EAAE,CAErB;IAED,QAAQ,UAAW,MAAM,UAKxB;IAED,WAAW,UAAW,MAAM,UAK3B;IAED,YAAY,aAyBX;IA4FQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI;IAcjD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI;IAOjD,KAAK,aAEJ;IAED,IAAI,aAeH;IAEQ,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAqBlD,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,QAAQ,EAAE,UAAU,GAAG,SAAS,KAAK,IAAI,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAqB3I,MAAM,UAAgB,MAAM,WAAW,GAAG,EAAE,KAAG,OAAO,CAAC,UAAU,CAAC,CAKjE;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webWorkerSupport.d.ts","sourceRoot":"","sources":["../../src/MessageHandling/webWorkerSupport.ts"],"names":[],"mappings":"AASA,qBAAa,aAAa;;;IAuCtB,cAAc,SAAe,GAAG,mBAG/B;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app_ww.d.ts","sourceRoot":"","sources":["../../src/testing/app_ww.ts"],"names":[],"mappings":""}
|