Erlang: использование gen_event global для удаленного менеджера
Я могу нормально запустить мою структуру событий, когда я регистрирую ее локально:
gen_event:start_link({local, foo_event_container}).
gen_event:add_handler(foo_event_container, foo_event_handler, []).
Вызов метода register () показывает foo_event_container, а когда я отправляю ему сообщения, они отображаются в обработчике.
Тем не менее, когда я перезагружаю узел и пытаюсь
gen_event:start_link({global, foo_event_container}).
register () НЕ показывает контейнер, и когда я пытаюсь добавить обработчик к нему, я получаю
** exception exit: noproc
in function gen:call/4
in call from gen_event:rpc/2
Sasl не предоставляет никакой дополнительной информации, и поиск этой проблемы приводит к предположению, что оболочка, в которой запущен контейнер, была уничтожена, что здесь не так, поскольку я пытаюсь получить к нему доступ с того же узла!
1) Есть идеи, что здесь происходит?
2) Является ли использование удаленного контейнера наилучшим дизайном, или было бы лучше, чтобы каждый сервер использовал локальные контейнеры, которые отправляют сообщения удаленному процессу?
Спасибо!
1 ответ
Локальная регистрация и глобальная регистрация являются отдельными пространствами имен. Элементы, зарегистрированные локально, не отображаются как глобальные регистрации и наоборот. (Кроме того, локальные регистрационные имена должны быть атомами, в то время как глобальные имена могут быть терминами)
Ваша глобальная регистрация должна появиться в global:registered_names/0
и вы можете отправить в глобально зарегистрированные процессы либо с global:send/2
или глядя на пид с global:whereis_name/1
и отправлять сообщения на этот пид как обычно.
Вы должны иметь возможность добавить обработчик, выполнив что-то вроде gen_event:add_handler({global, Name}, Handler, Args)
, Наиболее gen_*
модули содержат код для обработки имен процессов, таких как {global, Name}
сделать global
поиск для вас.
Наконец, если вы start_link
процесс из оболочки и затем вычисление выражения, которое вызывает сбой оболочки, этот процесс будет прерван - он был просто уничтожен ошибкой оболочки по ссылке. Запустите его без ссылки, или start_link под супервизором, если вы хотите избежать этого. Обычно плохая идея связать что-либо с процессом оболочки, так как опечатки затем отключат процессы, с которыми вы работаете.