我有一个拥有两个工作进程的主管:一个处理与远程服务器连接的TCP客户端和一个处理连接协议的FSM。
处理子进程中的TCP错误会严重影响代码。所以我更喜欢“让它崩溃”,但这有一个不同的问题:当服务器无法访问时,将很快达到最大重启次数,并且主管将与我的整个应用程序一起崩溃,这对于这个案例。
我想要的是采用后退的重启策略;如果失败了,那么如果主管知道何时由于崩溃而重新启动(即将其作为参数传递给init
函数)就足够了。我找到this mailing list thread,但有更正式/更好的测试解决方案吗?
答案 0 :(得分:5)
我多次使用erlang时遇到过这个问题并尝试了很多解决方案。我认为我发现的最好的最好的办法就是有一个由主管启动的额外流程,并启动可能崩溃的流程。
它在启动时启动孩子,等待孩子退出并重新启动孩子(延迟)或适当退出。我认为这比后退服务器(你链接到的)更简单,因为你只需要保持关于一个孩子的状态。
我使用的另一个解决方案是必须将子进程作为瞬态启动,并有一个单独的进程,轮询并重新启动任何已崩溃的进程。
答案 1 :(得分:5)
您可能会发现我们的supervisor cushion是一个很好的起点。我使用它会减慢重新启动必须正在运行的东西,但在启动时很快失败(例如遇到资源问题的端口)。
答案 2 :(得分:1)
首先,您希望通过在初始化中使用process_flag(trap_exit, true)
来提前终止孩子。
然后您需要决定延迟重启的时间,例如10秒,在
中执行此操作handle_info({'EXIT', _Pid, Reason}, State) ->
erlang:send_after(10000, self(), {die, Reason}),
{noreply, State};
最后,让进程死于
handle_info({die, Reason}, State) ->
{stop, Reason, State};