Erlang: simple pubsub for processes - is my approach ok?

Disclaimer: I'm pretty new to Erlang and OTP.

I want a simple pubsub in Erlang / OTP, where processes can subscribe to some kind of "hub" and receive a copy of messages sent to this center.

I know about gen_event , but it processes events in a single event dispatcher process, while I want each subscriber to be a separate, standalone process. In addition, I could not get control of the gen_event handlers. Unfortunately, the Google results were full of XMPP (Ejabberd) and RabbitMQ connections, so I did not find anything that could be related to my idea.

My idea is that such a pubsub model can easily be mapped to a watch tree. So I decided to extend the supervisor (a gen_server under the hood) to send a broadcast message to all of my children.

I hacked this in my quick and dirty regular dispatcher behavior:

 -module(dispatcher). -extends(supervisor). -export([notify/2, start_link/2, start_link/3, handle_cast/2]). start_link(Mod, Args) -> gen_server:start_link(dispatcher, {self, Mod, Args}, []). start_link(SupName, Mod, Args) -> gen_server:start_link(SupName, dispatcher, {SupName, Mod, Args}, []). notify(Dispatcher, Message) -> gen_server:cast(Dispatcher, {message, Message}). handle_cast({message, Message}, State) -> {reply, Children, State} = supervisor:handle_call(which_children, dummy, State), Pids = lists:filter(fun(Pid) -> is_pid(Pid) end, lists:map(fun({_Id, Child, _Type, _Modules}) -> Child end, Children)), [gen_server:cast(Pid, Message) || Pid <- Pids], {noreply, State}. 

However, although everything seems to work fine at a glance (children receive messages and restart smoothly when they fail), I wonder when it was a good idea.

Can someone please criticize (or approve) my approach and / or recommend some alternatives?

+7
source share
4 answers

From your code, it seems to me that the gen_event handlers are perfect.

Handler callbacks are called from one central process sending messages, but these callbacks should not work much.

So, if you need a stand-alone process with its status for subscribers, just send a message in the callback.

Usually these stand-alone processes will be gen_servers, and you simply call gen_server: drop your event callbacks.

Surveillance is a separate issue that can be handled by the conventional surveillance infrastructure that ships with OTP. How you want to control depends on the semantics of your subscriber processes. If they are all the same servers, you can use simple_one_for_one , for example.

In the init callback of the subscriber processes, you can place the gen_event:add_handler calls to add them to the event manager.

You can even use the event dispatcher as a supervisor if you use the gen_event:add_sup_handler to add your processes, if the semantics are right for you.

Better Online Resources for Understanding gen_event: Find Out About You in Erlang Chapter

Otherwise, Erlang books have an introduction to gen_event. Probably the most thorough you can find in Erlang and OTP in action

Oh, and BTW: I wouldn't hack your own supervisors for this.

+9
source

I recently used gproc to implement pubsub. The example from readme does the trick.

 subscribe(EventType) -> %% Gproc notation: {p, l, Name} means {(p)roperty, (l)ocal, Name} gproc:reg({p, l, {?MODULE, EventType}}). notify(EventType, Msg) -> Key = {?MODULE, EventType}, gproc:send({p, l, Key}, {self(), Key, Msg}). 
+11
source

A very simple example where you do all this is in my most basic chat_demo , which is a simple web chat server. Take a look at chat_backend.erl (or chat_backend.lfe if you need parentheses), which allows users to subscribe, and then they will be sent all the messages that come to the server. It does not fit into the observation trees, although the modification is simple (although proc_lib used to get more efficient error messages).

+1
source

Sometimes I read about ΓΈMQ (ZeroMQ), which has a bunch of bindings to various programming languages.

http://www.zeromq.org/

http://www.zeromq.org/bindings:erlang

If this should not be a pure erlang solution, this may be a choice.

-2
source

All Articles