2017-01-23 10 views
2

У меня есть менеджер событий, работающий в своем собственном узле Erlang. Я хотел бы использовать его как простой брокер событий и позволить другим приложениям на других узлах подписываться на него, добавляя свой собственный обработчик событий.Возможно ли добавить локальный обработчик событий в удаленный диспетчер событий

Моя установка тестирования выглядит так (извините страшная отступы) enter image description here

При запуске этого я получаю сообщение об ошибке, как:

{'EXIT',{undef,[{event_handler_a,init,[[]],[]}, 
       {gen_event,server_add_handler,4, 
          [{file,"gen_event.erl"},{line,429}]}, 
       {gen_event,handle_msg,5,[{file,"gen_event.erl"},{line,270}]}, 
       {proc_lib,init_p_do_apply,3, 
          [{file,"proc_lib.erl"},{line,247}]}]}} 

Так что теперь, мне интересно, если я делаю что-то неправильно или если эта архитектура просто невозможна. Поскольку логика в обработчике событий полностью связана с моим приложением, я бы предпочел сохранить его в моей версии приложения. Наличие обработчика событий для каждого приложения внутри моей версии диспетчера событий, вероятно, скоро станет беспорядочным.

+1

Я не знаю много о 'gen_event', но эта ошибка выглядит как' gen_event' попытался вызвать 'event_handler_a: INIT ([])' и что либо модуль или эта функция не была определена/загружена на этом узле Erlang. – Dogbert

+0

@Dogbert Я забыл об этом. Если диспетчер событий вызывает обратный вызов init/1 из обработчика события, ему нужно будет указать имя узла. К сожалению, документ показывает 'add_handler (EventMgrRef, Handler, Args) -> Результат' с' Handler = Module | {Module, Id} ' – ITChap

+0

Я думаю, вы можете передать это как' Args', поэтому 'gen_event: add_handler (_, _, node1 @ host1)'. – Dogbert

ответ

5

Нет, это невозможно. gen_event работает немного иначе, чем в других моделях поведения, поскольку код в вашем модуле обратного вызова (тот, который вы передаете как аргумент gen_event:add_handler/3) запускается в тем же процессом, что и диспетчер событий. Поэтому, если диспетчер событий работает на удаленном узле, обработчик события будет работать на том же узле.

Одним из способов достижения этого является создание модуля обратного вызова обработчика событий, который передает события процессу на нужный узел. Вы могли бы сделать что-то вроде этого:

gen_event:add_handler({event_manager, [email protected]}, my_event_forwarder, [self()]). 
+0

Вот что я подумал. Я мог бы также создать очень общий обработчик, который принимает 'fun()' как его аргумент init и просто передает все события этому 'fun()'. Подписка будет заключаться в том, чтобы всегда добавлять один и тот же модуль обработчика с различными 'fun()', чтобы делать разные вещи. – ITChap

+1

Обратите внимание, что модуль, в котором определяется веселье, должен быть загружен на узле, где он вызывается. – legoscia