【问题标题】:How to detect erl_call disconnect如何检测erl_call断开连接
【发布时间】:2012-11-03 21:08:49
【问题描述】:

我有一个由 erl_call 触发的 erlang 服务。 erl_call 将进行一个长调用,例如 "gen_server:call(?SERVER, do, infinity)" 以等待结果。如果 erlang 服务关闭,则 erl_call 将返回。但是如果 erl_call 被中断(使用 CTRL-C),erlang 服务不会收到任何消息。

我检查了 appmon 和 pman。 erl_call 启动的进程在 erl_call 断开后不会死掉。所以链接/监控到那个过程是行不通的。如何检测 erl_call 已断开连接?

【问题讨论】:

    标签: erlang call erl


    【解决方案1】:

    在你的handle_call 函数中有第二个。参数来自 :: {pid(), tag()}

    您可以在处理请求之前在handle_call 中调用monitor(process, FromPid),以便在您的erl_call 节点断开连接时收到DOWN 消息。但请注意,除非您生成一个单独的进程或使用 gen_server:reply() 的延迟回复,否则您将无法在当前 handle_call 完成之前处理 DOWN 消息。

    例如:这是我们的 handle_call 子句:

    handle_call(test, {From, _}=X, State) ->
        erlang:monitor(process, From),
    
        spawn(fun() ->
           timer:sleep(10000),
           io:format("### DONE~n", []),
           gen_server:reply(X, ok) end),
    
        {noreply, State}.
    

    接下来我们赶上DOWN:

    handle_info(Info, State) ->
        io:format("### Process died ~p~n", [Info]),
        {noreply, State}.
    

    接下来我从命令行生成 erl_call: erl_call -c 123 -n test -a 'gen_server call [a, test, infinity]'

    然后按 Ctrl-C

    10 秒后在 gen_server 控制台中我看到:

    ### DONE            
    ### Process died {'DOWN',#Ref<0.0.0.41>,process,<0.44.0>,normal}
    

    【讨论】:

    • 您好,谢谢您的回复。我使用延迟回复并让 erl_call 等待。我尝试了链接/监视器。但它不起作用。使用 pman,我可以找出哪个进程在等待结果。中断erl_call后,进程还活着,所以我没有收到任何EXIT/DOWN消息。
    • 嗯,当延迟调用完成后,你最终会收到DOWN消息。我刚刚检查过,它确实有效。
    • 我可以在回复前收到“DOWN”消息吗?如果 erl_call 连接丢失,我想停止进程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 1970-01-01
    • 2022-11-05
    • 2012-12-10
    相关资源
    最近更新 更多