免责声明:我对 Erlang 和 OTP 很陌生。
我想要一个 Erlang/OTP 中的简单 pubsub,其中进程可以在某个“集线器”订阅并接收发送到该集线器的消息副本。
我知道gen_event
,但它在一个事件管理器进程中处理事件,而我希望每个订阅者都是一个独立的、自治的进程。此外,我无法接受 grokgen_event
的处理程序监督。不幸的是,谷歌搜索结果充满了 XMPP (Ejabberd) 和 RabbitMQ 链接,所以我没有找到任何与我的想法相关的内容。
我的想法是这样的 pubsub 模型无缝地映射到监督树。所以我想扩展主管(gen_server
引擎盖下的一个),以便能够向它的所有孩子发送演员信息。
我已经在我的快速而肮脏的自定义“调度程序”行为中破解了这个:
-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}.
然而,虽然乍一看一切似乎都很好(孩子们收到消息并在失败时无缝重新启动),但我想知道这是否是个好主意。
请问有人可以批评(或批准)我的方法,和/或推荐一些替代方案吗?