Отказ от ответственности: я новичок в Erlang и OTP.
Мне нужен простой pubsub в Erlang/OTP, где процессы могли бы подписываться на какой-то «концентратор» и получать копии сообщений, которые были отправлены на этот концентратор.
Я знаю про gen_event
, но он обрабатывает события в одном единственном процессе менеджера событий, а я хочу, чтобы каждый подписчик был отдельным, автономным процессом. Кроме того, мне не удалось получить контроль над обработчиками gen_event
. К сожалению, результаты Google были полны ссылок 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}.
Однако, хотя на первый взгляд кажется, что все работает нормально (дети получают сообщения и плавно перезапускаются в случае сбоя), мне интересно, когда это было хорошей идеей.
Может ли кто-нибудь покритиковать (или одобрить) мой подход и/или порекомендовать какие-то альтернативы?
gen_event
, спасибо. - person drdaeman   schedule 31.08.2011