erlang - монитор отправляет информацию в оболочку, а не на gen_server

Я пытаюсь подключить gen_server к другому gen_server, и во время подключения серверы должны контролировать друг друга и знать, когда сервер вышел из строя, либо весь узел, либо серверный процесс. после того, как я делаю первую ссылку start_link и один из серверов выходит из строя, другой сервер получает сообщение от монитора в коде (функция handle_info активирована), но когда это происходит во второй раз, монитор отправляет информацию непосредственно в оболочку ( сообщение не проходит через handle_info и направляется непосредственно в оболочку, видимую только с помощью flush() внутри оболочки), и сервер, который должен был получать предупреждения от монитора, не получает никаких сообщений. мой код на стороне отправки:

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.

пожалуйста, кто-нибудь может сказать мне, почему это происходит?

то же самое происходит для мониторинга узла или процесса.


person omerfeld    schedule 16.08.2018    source источник


Ответы (2)


Если вы получаете второе сообщение монитора в оболочке, это происходит потому, что вы вызываете функцию подключения в контексте оболочки.

Проверьте, как вы вызываете эту функцию, это должно быть сделано в контексте сервера, то есть внутри функции handle_call, handle_cast или handle_info.

person Pascal    schedule 17.08.2018

после того, как я делаю первую ссылку start_link и один из серверов падает, другой сервер получает сообщение от монитора в коде, но когда это происходит во второй раз

Похоже, вы запускаете новый сервер после сбоя сервера. Вы вызываете monitor() на новом сервере Pid?

Монитор запускается только один раз, после что он удален как из процесса мониторинга, так и из контролируемого объекта. Мониторы запускаются, когда отслеживаемый процесс или порт завершается, не существует в момент создания или если соединение с ним потеряно. В случае со связью мы теряем знание о том, существует она еще или нет. Мониторинг также отключается при вызове demonitor/1.

person 7stud    schedule 16.08.2018
comment
я, функция подключения вызывает монитор каждый раз, проблема в том, что сообщение с монитора попадает непосредственно в оболочку и не переходит в handle_info, куда оно должно идти. - person omerfeld; 16.08.2018