Erlang:使用gen_event global作为远程管理器

时间:2011-02-18 20:47:53

标签: erlang gen-event

我可以在本地注册时启动我的事件框架:

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

调用registered()会显示foo_event_container,当我向其发送消息时,它们会显示在处理程序中。

但是,当我重新启动节点并尝试

gen_event:start_link({global, foo_event_container}).

registered()不显示容器,当我尝试向其添加处理程序时 我得到了

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

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

1)有什么想法在这里发生了什么? 2)拥有一个最佳设计的远程容器,或者让每个服务器使用本地容器向所有远程进程发送消息会更好吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

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

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

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

最后,如果你start_link来自shell的进程然后评估导致shell崩溃的表达式,那么该进程将被终止 - 它只是通过链接被shell错误杀死了。如果你想避免这种情况,可以在没有链接的情况下启动它,或者在主管下启动它。将一些东西链接到shell进程通常是一个坏主意,因为拼写错误会关闭你正在使用的进程。