什么代码将从**删除(timedout)连接**恢复?

时间:2015-08-06 15:05:16

标签: multithreading erlang gen-server

我在一个系统上有一个gen_server,在另外四个系统上有4个客户端。当gen_server报告“**删除(超时)连接**”时,代码按预期运行3或4天。因为客户端可以在gen_server启动之前变为活动状态,所以客户端在每次调用gen_server之前都会执行此代码:

connect_IPDB() ->
% try every 5 sec to connect to the server
case net_kernel:connect_node(?SERVER) of
    % When connected wait an additional 5 seconds for stablilty
    true -> timer:sleep(5000);
    false -> 
        timer:sleep(5000),
        connect_IPDB()
end.

当按照任何顺序启动服务器或客户端时,这可以预期。它们都在服务器上执行时连接并显示在nodes()中。

这是问题所在。在“**删除(超时)连接**”错误之后的某个时间,nodes()显示所有节点,这意味着客户端没有挂起并执行了上述代码。但是,与timedout节点的通信尚未恢复。如何在重新启动客户端的情况下重新建立连接?顺便说一句,重启客户端确实解决了这个问题。

任何帮助,谢谢。

1 个答案:

答案 0 :(得分:0)

我终于找到了问题和解决方案。我的暂停是因为有问题的客户端暂停(他们是虚拟机),所以他们可以备份。因为它们被暂停,当它们被取消暂停时,客户端的主管没有看到任何问题,因此不会重新启动该程序。

修复方法是将connect_IPMD更改为:

connect_IPDB() ->
% See if we are connected to the server. Is the server in the list?
case lists:filter(fun(X) -> string:str(atom_to_list(X),atom_to_list(?SERVER))== 1 end, nodes(connected)) of
    % If empty, then not in list, enter the reconnect loop
    [] -> 
        connect_IPDB("Reconnect");
    % any thing else, then we are connected, so proceed
    _ -> ok 
end.
connect_IPDB(_Reconnect) ->
case net_kernel:connect_node(?SERVER) of
    % When connected wait an additional 5 seconds for stablilty
    true -> 
        timer:sleep(5000),
        Ips = gen_server:call({global, ?SERVER},getall_ips),
        % Re-initialize the iptables
        removechain(),
        createchain(),
        % Load the Ips into the local iptables f2bchain
        load_ips(Ips),
        % restart the ntpd 
        os:cmd("service ntpd restart");
    false -> 
        timer:sleep(5000),
        connect_IPDB("Reconnect")
end.

当客户端退出暂停时,这具有重置客户端时钟(重新启动NTPD)的附加优势。

我将离开主管处理"真实"这种自我诱导的失败。