2

当我在本地注册它时,我可以很好地启动我的事件框架:

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}).

注册()不显示容器,当我尝试向它添加处理程序时,我得到

** exception exit: noproc
     in function  gen:call/4
     in call from gen_event:rpc/2

Sasl 没有提供任何额外的信息,谷歌搜索这个问题会产生一个猜测运行容器的 shell 已经被杀死,这不是这里的情况,因为我试图从同一个节点访问它!

1)有什么想法吗?
2)拥有一个远程容器是最好的设计,还是让每个服务器都使用本地容器来将消息都发送到远程进程会更好?

谢谢!

4

1 回答 1

2

本地注册和全局注册是独立的命名空间。本地注册的项目不会显示为全局注册,反之亦然。(另外,本地注册名称必须是原子,而全局名称可以是术语)

您的全局注册应该显示在global:registered_names/0其中,您可以使用global:send/2或通过查找 pidglobal:whereis_name/1并像往常一样向该 pid 发送消息来发送到全局注册的进程。

您应该能够通过执行类似的操作来添加处理程序gen_event:add_handler({global, Name}, Handler, Args)。大多数gen_*模块都包含处理进程名称的代码,例如为您{global, Name}进行global查找。

最后,如果您start_link是来自 shell 的进程,然后评估导致 shell 崩溃的表达式,则该进程将被终止 - 它只是通过链接被 shell 错误杀死。如果您想避免这种情况,请在没有链接的情况下启动它,或者在主管下启动它。将某些内容链接到 shell 进程通常是个坏主意,因为输入错误会关闭您正在使用的进程。

于 2011-02-18T21:40:51.517 回答