erlang-监视器将信息发送到shell而不是gen_server

时间:2018-08-16 17:01:36

标签: erlang monitor gen-server

我正在尝试将一台gen_server连接到另一台gen_server,并且在连接期间,服务器需要互相监视,并知道服务器何时崩溃,整个节点还是服务器进程。在我执行第一个start_link之后,其中一台服务器崩溃后,另一台服务器从代码中的监视器获取了一条消息(handle_info函数已激活),但是第二次发生时,监视器将信息直接发送到外壳程序(消息不会通过handle_info传递,而是直接转到仅在shell内使用flush()可见的shell),并且假定从监视器发出警报的服务器未收到任何消息。 我在发送方的代码:

handle_call({connect, Node, Who}, _From, _State) ->
  case Who of
    cdot -> ets:insert(address, {cdot, Node}), ets:insert(address, 
{Node, cdot}), monitor_node(Node, true);
    cact -> ets:insert(address, {cact, Node}), ets:insert(address, 
{Node, cdot}), monitor_node(Node ,true);
    ctitles -> ets:insert(address, {ctitles, Node}), 
ets:insert(address, {Node, cdot}), monitor_node(Node, true);
    _-> ok
  end,
  [{_, Pid2}] = ets:lookup(?name_table3, pidGui),
  Pid2 ! {db, "Node "++ atom_to_list(Who) ++ " connected"}, %print to 
gui witch node was connected
  {reply, {{node(), self()}, connected}, node()};

接收方的是:

connect() ->
  {{Node, Pid}, Connected} = gen_server:call(server_node(), {connect, 
node(), cact}),
  monitor_node(Node, true),
  monitor(process, Pid),
  Connected.

请任何人告诉我为什么会这样吗?

节点或进程监视也是如此

2 个答案:

答案 0 :(得分:2)

如果在shell中收到第二条监视消息,那是因为您在shell上下文中调用了connect函数。

检查如何调用此函数,它必须在服务器上下文中完成,这意味着在handle_call,handle_cast或handle_info函数内部。

答案 1 :(得分:0)

  

在我执行第一个start_link之后,其中一台服务器崩溃了   其他服务器在代码中从监视器获取消息,但是当它   发生第二次

听起来好像您在服务器崩溃后正在启动新服务器。您是否在新服务器Pid上调用monitor()?

  

A monitor is triggered only once,之后将其从   监视过程和被监视实体。显示器被解雇   当受监视的进程或端口终止时,该端口不存在   创建时刻或与它的连接丢失。在这种情况下   与连接有关,如果事实仍然存在,我们将失去有关事实的知识   或不。调用demonitor / 1时,监视也会关闭。