Erlang: использование gen_event global для удаленного менеджера - PullRequest
2 голосов
/ 18 февраля 2011

Я могу нормально запустить мою структуру событий, когда я регистрирую ее локально:

gen_event:start_link({local, foo_event_container}).
gen_event:add_handler(foo_event_container, foo_event_handler, []).

Вызов зарегистрированного () показывает 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 Ответ

2 голосов
/ 19 февраля 2011

Локальная регистрация и глобальная регистрация являются отдельными пространствами имен. Элементы, зарегистрированные локально, не отображаются как глобальные регистрации и наоборот. (Также локальные регистрационные имена должны быть атомами, а глобальные имена могут быть терминами)

Ваша глобальная регистрация должна отображаться в global:registered_names/0, и вы можете отправлять глобально зарегистрированным процессам либо с global:send/2, либо просматривая pid с помощью global:whereis_name/1 и отправляя сообщения на этот pid как обычно.

Вы должны иметь возможность добавить обработчик, выполнив что-то вроде gen_event:add_handler({global, Name}, Handler, Args). Большинство gen_* модулей содержат код для обработки имен процессов, таких как {global, Name}, для поиска global.

Наконец, если вы start_link обработаете процесс из оболочки, а затем оцените выражение, вызывающее сбой оболочки, этот процесс будет прерван - он был просто уничтожен ошибкой оболочки по ссылке. Запустите его без ссылки, или start_link под супервизором, если вы хотите избежать этого. Обычно плохая идея связать что-либо с процессом оболочки, так как опечатки затем отключат процессы, с которыми вы работаете.

...