为什么net_kernel:monitor_nodes / 2不为sname节点传递nodeup / nodedown消息?

时间:2013-11-12 21:45:45

标签: erlang distributed-system

我启动一个短名称的主节点,并让它运行一个进程来监视节点的上下行消息。

> erl -sname master -cookie monster
Erlang R15B03 (erts-5.9.3) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false] [dtrace]

Eshell V5.9.3  (abort with ^G)
(master@pencil)1> c("/tmp/monitor.erl").
{ok,monitor}
(master@pencil)2> Pid = monitor:start().
<0.44.0>
(master@pencil)3> Pid ! running.
RECV :: running
running
(master@pencil)4> net_adm:names().
{ok,[{"master",52564}]}

此时只有master节点正在运行。我在同一台机器上启动第二个节点:

> erl -sname client -cookie monster
Erlang R15B03 (erts-5.9.3) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false] [dtrace]

Eshell V5.9.3  (abort with ^G)
(client@pencil)1>

并等待一分钟,只是因为我正在阅读文档错误,并且有一个复杂的净滴答。什么都没有,所以在掌握我强制连接:

(master@pencil)5> net_adm:names().
{ok,[{"master",52564},{"client",52579}]}
(master@pencil)6>

并且我的小监视器进程没有任何内容。现在,如果我执行相同的事情,但使用长名称 - 即-name - 这可以正常工作。不过,我感到很惊讶,因为net_kernel文档没有提到这一点。这是怎么回事?


以上是上面引用的monitor.erl

-module(monitor).

-export([start/0]).

start() ->
    spawn_link(fun init_loop/0).

%%%===================================================================
%%% Internal Functions
%%%===================================================================

init_loop() ->
    net_kernel:monitor_nodes(true, []),
    loop().

loop() ->
    receive
    Msg -> io:format(user, "RECV :: ~p~n", [Msg])
    end,
    loop().

1 个答案:

答案 0 :(得分:2)

net_kernel:monitor_nodes/2 绝对为具有短名称和长名称的节点提供nodeup / nodedown消息。

但是,只有在连接节点时才会传递nodeup消息,如文档中所述。为什么你得到带有nodeup的{​​{1}}消息是一个谜(这里无法再现),因为-name根本不连接节点。它只连接到epmd以获取本地注册节点的列表。它甚至会列出具有不同cookie的节点。

如果您使用net_adm:names/0(或net_adm:ping/1电话)将客户端连接到主服务器(或其他方式),则监控过程将收到rpc消息。