2012-11-15 123 views
0

我有一个由erl_call触发的erlang服务。 erl_call将会像“gen_server:call(?SERVER,do,infinity)”一样进行长时间调用,以等待结果。如果erlang服务关闭,erl_call将返回。但是,如果erl_call被中断(使用CTRL-C),erlang服务就不会收到任何消息。如何检测erl_call断开连接

我用appmon和pman检查。在erl_call断开连接后,erl_call开始的进程不会死亡。因此,链接/监视该进程不起作用。如何检测erl_call已断开连接?

回答

0

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

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

例如:这里是我们的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:

接下来,我在命令行erl_call产卵: erl_call -c 123 -n测试-a“ gen_server呼叫[a,test,infinity]'

and hit Ctrl-C

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

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

嗨,谢谢你的回复。我使用延迟回复并保持erl_call等待。我尝试链接/监视器。但它不起作用。用pman,我可以找出哪个进程正在等待结果。在中断erl_call之后,进程仍然活着,所以我没有收到任何EXIT/DOWN消息。 – shian

+0

那么,当延迟的呼叫完成后,您最终会收到DOWN消息。我刚刚检查过,确实有效。 – 2012-11-15 14:27:15

+0

我已经更新了答案 – 2012-11-15 14:33:52