Erlang:初始化后在另一个节点上启动 gen_server 失败

Erlang: starting gen_server on another node fails after init

我试图在另一个节点上 运行 gen_server 进行一些修复。所以我有一个常见的 gen_server class 看起来像这样

start(FileName) ->
  start_link(node(), FileName).

start_link(ThisNode, FileName) ->
  gen_server:start_link({local, ?MODULE}, ?MODULE, [ThisNode, FileName], []).

init([ThisNode, FileName]) ->
  process_flag(trap_exit, true),
  {ok, Terms} = file:consult(FileName),
  {A1, B1, C1} = lists:nth(1,Terms),
  place_objects(A1, B1, C1).

现在我想启动多个节点,这些节点将 运行 相同 gen_server 并以某种方式相互通信,并使用另一个节点来协调它。 (所有这些节点都在我的本地终端上启动)。

所以我在一个终端中使用 erl -sname bar 启动一个新节点,我打算 运行 gen_server,并在此节点上编译 gen_server 模块。然后我启动另一个名为 'sup' 的节点,我打算将其用作所有其他节点的协调器。如果我在 bar 上 运行 命令 my_gen_server:start("config_bar.txt").,它成功地 returns 但是当我在 sup 上 运行 命令 rpc:call('bar@My-MacBook-Pro', my_gen_server, start, ["config_bar.txt"]). 时,它成功地 returns 从init 方法(我通过放入日志来检查这个)但紧接着,我得到这个错误:

{ok,<9098.166.0>}
(sup@My-MacBook-Pro)2> =ERROR REPORT==== 21-Feb-2022::11:12:30.443051 ===
** Generic server my_gen_server terminating 
** Last message in was {'EXIT',<9098.165.0>,
                               {#Ref<0.3564861827.2990800899.137513>,return,
                                {ok,<9098.166.0>}}}
** When Server state == {10,10,#Ref<9098.1313723616.3973185546.82660>,
                         'bar@My-MacBook-Pro'}
** Reason for termination ==
** {#Ref<0.3564861827.2990800899.137513>,return,{ok,<9098.166.0>}}

=CRASH REPORT==== 21-Feb-2022::11:12:30.443074 ===
  crasher:
    initial call: my_gen_server:init/1
    pid: <9098.166.0>
    registered_name: my_gen_server
    exception exit: {#Ref<0.3564861827.2990800899.137513>,return,
                     {ok,<9098.166.0>}}
      in function  gen_server:decode_msg/9 (gen_server.erl, line 481)
    ancestors: [<9098.165.0>]
    message_queue_len: 0
    messages: []
    links: []
    dictionary: []
    trap_exit: true
    status: running
    heap_size: 1598
    stack_size: 29
    reductions: 3483
  neighbours:

我似乎无法弄清楚是什么原因导致了错误,如果有什么我需要添加到我的 gen_server 代码来修复它。真的很感谢这方面的帮助!

远程节点中的 gen_server 链接到为 rpc 调用创建的临时进程。 由于此临时进程以不同于 normal(rpc 调用的实际结果)的术语退出,因此退出信号传播到 gen_server,将其杀死。

您可以使用 gen_server:start 而不是 gen_server:start_link 或者,如果您希望 gen_server 成为监督树的一部分,请指示其主管生成它:

rpc:call('bar@My-MacBook-Pro',  my_gen_sup, start_child, ["config_bar.txt"]).