-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcluster_events.js
More file actions
90 lines (86 loc) · 2.75 KB
/
Copy pathcluster_events.js
File metadata and controls
90 lines (86 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
const cluster = require('cluster');
const {EventEmitter} = require('events');
const _ = require('lodash');
const ID_SYMBOL = 'ClusterEventEmitter';
const Action = {
MASTER_EMIT: 'master_emit',
WORKER_EVENT: 'worker_event',
};
class ClusterEventEmitter {
#events = new EventEmitter();
#label;
constructor(label){
this.#label = label;
if (cluster.isPrimary)
return void this.#initMaster();
this.#initWorker();
}
#initMaster(){
_.values(cluster.workers)
.forEach(w=>this.#initSpawnedWorker(w));
cluster.on('fork', w=>this.#initSpawnedWorker(w));
}
#initSpawnedWorker(worker){
worker.on('message', msg=>{
if (!this.#shouldHandleMessage(msg))
return;
let {action, event, data=[], from} = msg;
switch (action) {
case Action.MASTER_EMIT:
this.#events.emit(event, ...data);
_.values(cluster.workers).filter(w=>w.id!=from).forEach(w=>w.send({
sym: ID_SYMBOL,
label: this.#label,
action: Action.WORKER_EVENT,
event,
data,
}));
break;
}
});
}
#initWorker(){
process.on('message', msg=>{
if (!this.#shouldHandleMessage(msg))
return;
let {action, event, data=[]} = msg;
switch (action) {
case Action.WORKER_EVENT:
this.#events.emit(event, ...data);
break;
}
});
}
#shouldHandleMessage(msg){
return _.isObject(msg)&&msg.sym==ID_SYMBOL&&msg.label==this.#label;
}
emit(event, ...args){
this.#events.emit(event, ...args);
if (cluster.isPrimary) {
_.values(cluster.workers).forEach(w=>w.send({
sym: ID_SYMBOL,
label: this.#label,
action: Action.WORKER_EVENT,
event,
data: args,
}));
} else {
process.send({
sym: ID_SYMBOL,
label: this.#label,
from: cluster.worker.id,
action: Action.MASTER_EMIT,
event,
data: args,
});
}
}
on(event, cb){ this.#events.on(event, cb); }
off(event, cb){ this.#events.off(event, cb); }
once(event, cb){ this.#events.once(event, cb); }
removeAllListeners(event){ this.#events.removeAllListeners(event); }
static dispatch(label, event, ...args){
new ClusterEventEmitter(label).emit(event, ...args);
}
};
module.exports = {ClusterEventEmitter};