Simple Friendly Node.js Channel for communications between processes.
Warinig: This module is deprecated, please check out sfn-worker instead.
This module can be used as a process manager, when you initiate a
new Channel
, a new worker process will be forked. You can keep a channel
alive, so when the worker exits accidentally, a new one will be created to
replace it.
This module is designed as convenient as it can, many of its methods can be used both in the master or in a worker process, and you can add event listeners and emit events both in the master or in the worker process.
This module uses predictable and user-defined IDs to differ channels, so you can always know which is which.
npm install sfn-channel
const Channel = require("sfn-channel");
if (Channel.isMaster) {
// Master process
// Create two channels listens to worker processes A and B, and keep them
// alive.
new Channel("A", true);
new Channel("B", true);
// Do logics when the channel is online.
Channel.on("online", (channel) => {
channel.on("greeting from worker", (msg) => {
console.log("Worker %s: %s", channel.id, msg);
// greet back
channel.emit("greeting from master", `Hello, worker ${channel.id}!`);
});
});
} else {
// Worker process
Channel.on("online", channel => {
channel.emit("greeting from worker", `Hi, master, I'm worker ${channel.id}!`);
channel.on("greeting from master", msg => {
console.log("Master: %s", msg);
}).on("greeting from another worker", (id, msg) => {
console.log("Worker %s: %s", id, msg);
// greet back
channel.to(id).emit("greeting back to another worker", channel.id, `Nice to meet you, worker ${id}!`);
}).on("greeting back to another worker", (id, msg) => {
console.log("Worker %s: %s", id, msg);
})
if (channel.id === "A") {
channel.to("B").emit("greeting from another worker", "A", `Hi, worker B, I'm worker A!`);
}
});
}
Whether the current process is the master process.
Whether the current process is a worker process, opposite to
Channel.isMaster
.
This constructor creates both a channel and a worker process, be aware you can
only create channels and workers in the master process. If you set keepAlive
to true
, then when the worker process accidentally exits, a new one will be
created to replace it immediately, thus keeping the channel always available.
The channel id
, unlike the worker id generated by cluster
or process
pid
, is user-defined and predictable, you can use any id you want to name
the channel. And whenever you want to send messages, you can always know the
channel id.
if(Channel.isMaster){
// Always create channels in the master process.
new Channel("A");
new Channel("B", true); // Keep B alive.
}
The channel id you specified.
Adds a listener function to an event. The handler
function will be
called every time the event
is triggered, it may accept parameters, which
are sent by the other end of the channel, or other workers.
channel.on("hi", (msg)=>{
console.log("worker says hi: '%s'", msg);
});
This method is very much the same as channel.on()
, except the handler
will
only be run once.
Emits an event
to the other end of the channel, data
will be send to that
end, so its event listeners can receive and manipulate them.
channel.emit("hi", `Hello, I'm worker ${channel.id}.`);
Sets receivers that the event will only be emitted to them.
channel.to("A").emit("hi", `Hello, I'm worker ${channel.id}.`);
Emits an event
to all worker ends of channels (the current channel
included). Remember, when you broadcast a message, it will always be sent to
worker ends of channels, so listening such an event in the master process is
meaningless and won't work.
The reason why the current channel included is meant to reduce your work, if some event acts the same in all workers, then your can just write one piece of code at where listens the event.
channel.broadcast("hi", `Hi everybody, I'm worker ${channel.id}.`);
This method allows you getting all workers forked by cluster
. If you provide
the argument cb
, it accepts one parameter, which is an object that carries
all worker objects. If you don't provide cb
, then a promise will be
returned, and the callback function of then()
is very much the same as cb
.
channel.getWorkers(workers=>{
// ...
});
// Or
channel.getWorkers().then(workers=>{
// ...
});
This method acts different in master process and in worker processes, when in master process, you can get the real workers, but in a worker process, you can just get an object that carries few details about those workers.
Terminates the current worker/channel. If this method is called, even if you
set the channel to keepAlive
, it will be terminated anyway.
Restarts the current worker/channel. If this method is called, even if you set
the channel not to keepAlive
, it will be restarted anyway.
The static version on()
can only listens two events: online
and exit
.
When a channel is created and ready for communications, online
event will be
triggered. When the channel is closed, exit
will be triggered.
Channel.on("online", channel=>{
console.log("Channel %s is online.", channel.id);
// ...
}).on("exit", channel=>{
console.log("Channel %s exits.", channel.id)
});
Be aware, binding a listener to exit
is optional, while online
is
required, and you must do any stuffs related to that channel
in the listener
function. This principle works both in master process or in worker processes.
Similar to the instantiated version, but can only be used in the master process.
If you want to send messages in the master process actively, you can call this
static version emit()
, its usage is pretty much the same as the instantiated
one. be aware this method will broadcast messages to every worker
process, unless you specify a receiver by calling Channel.to()
.
Similar to the instantiated version, but can only be used in the master process.
Be aware, you must call emit()
very after calling this method, because
its a static version, if you don't do this, there is no guarantee that its
state won't be changed when you calling emit()
after a while.
Channel.to("A").emit("event name", "Hi, worker A!");
Similar to the instantiated version, but can only be used in the master process.
Channel.broadcast("event name", "Hi, everyone, I'm your master!");
Similar to the instantiated version, but can only be used in the master process.
Channel.getWorkers(workers=>{
// ...
});
// Or
Channel.getWorkers().then(workers=>{
// ...
});
This method allows you getting the current channel in a worker process outside
the Channel.on("online")
scope. It's very helpful sometimes when you want to
get the the current channel, but you don't want to or it's hard to put your
code inside Channel.on("online")
.
If you don't pass a cb
function, then this method will return a Promise
.
Channel.on("online", channel=>{
// ...
});
// Outside the scope:
Channel.getChannel(channel=>{
// ...
});