Disclaimer: Je suis assez nouveau à Erlang et OTP.
Je veux un simple pubsub à Erlang / OTP, où les processus pourraient souscrire à un "moyeu" et recevoir une copie de messages envoyés à ce hub. p>
Je sais sur Mon idée est que ce modèle pubsub est parfaitement transparente dans l'arbre de supervision. J'ai donc pensé étendre le superviseur (un J'ai piraté cela dans mon rapide Comportement "Dispatcher" personnalisé sale: P> gen_event code>, mais il traite des événements dans un seul processus de gestionnaire d'événements, alors que je souhaite que chaque abonné soit un processus distinct et autonome. En outre, j'ai été incapable de grok
Gen_Event CODE> SUPERLERS DE MANUTLERS. Malheureusement, les résultats de Google étaient pleins de liens XMPP (Ejabberd) et de rabbbitmq, donc je n'ai rien trouvé de pertinent à mon idée. P>
gen_server code> sous la hotte) pour pouvoir envoyer un message de distribution à tous ses enfants. P>
-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}.
4 Réponses :
de votre code, il me semble que les gestionnaires Gen_Event sont une correspondance parfaite. P>
Les rappels de gestionnaire sont appelés à partir d'un processus central expédiant les messages, mais ces rappels ne devraient pas faire beaucoup de travail. P>
Donc, si vous avez besoin d'un processus autonome avec son propre état pour les abonnés, envoyez simplement un message dans le rappel d'événement. P>
Généralement, ces processus autonomes seraient GEN_SERVERS et vous appelleriez simplement Gen_Server: jeté de vos rappels événementiels. P>
Supervision est un problème distinct, qui peut être géré par l'infrastructure de supervision habituelle fournie avec OTP. La façon dont vous voulez faire une supervision dépend de la sémantique de vos processus d'abonnés. S'ils sont tous des serveurs identiques, vous pouvez utiliser un Dans le rappel code> init code> des processus d'abonné, vous pouvez mettre le Vous pouvez même utiliser le gestionnaire d'événements comme superviseur si vous utilisez le Ressources en ligne pour la compréhension de Gen_Event Meilleur: Décrochez un chapitre Erlang P>
Sinon, les livres Erlang ont tous une introduction Gen_Event. Probablement la plus complète que vous puissiez trouver dans Erlang et OTP en action P>
OH et BTW: Je ne voudrais pas pirater vos propres superviseurs pour cela. P> simple_one_for_one code> par exemple. P>
gen_event: add_handler code> les appels qui les ajoute au gestionnaire d'événements. P>
gen_event: add_sup_handler code> fonction pour ajouter vos processus si la sémantique de ce costume vous convient. P>
Un exemple de processus "supervise" A Gen_Event CODE> Handler peut être trouvé ici: Trapexit. org / gen_tevent_behavior_demystifié
Un problème avec les gestionnaires d'événements est qu'ils ne peuvent avoir qu'au plus un de chaque type de gestionnaire d'événements, donc si vous envoyez à nombre de types de même type, ce sera un gestionnaire qui leur envoie tous.
Il y a parfois, j'ai lu environ Ømq (Zeromq), qui a un tas de liaisons à différentes langages de programmation. P>
http://www.zeromq.org/bindings:erlang p>
S'il ne doit pas une solution pure erlang, cela pourrait être un choix. P>
Un exemple très simple où vous faites tout ce que vous faites vous-même est dans mon chat_demo qui est un simple Serveur de discussion Web basé sur le Web. Regardez chat_backend.erl code> (ou
chat_backend.lfe code> si vous aimez les parenthèses) qui permet aux utilisateurs de abonner em> et ils seront ensuite envoyés tous les messages arriver au backend. Il ne s'intègre pas dans les arbres de supervision, bien que la modification soit simple (bien qu'il utilise
proc_lib code> pour obtenir de meilleurs messages d'erreur). P>
J'ai récemment utilisé GPROC pour implémenter pubsub. L'exemple du Readme fait l'affaire.
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}).
Les messages sont-ils stockés et que de nouveaux processus se souscrivent à l'historique total. Ou est-ce que les messages ne sont transmis que du moment où un processus souscrit?
Le dernier; comme dans Redis ou 0 mq pub / sous. Je vais prendre un autre regard sur
gen_event code>, merci.