Erlang 在重新启动子系统时,主管是否阻止调用?
我试图了解这里发生了什么: 我有一个主管,它在不触发Erlang 在重新启动子系统时,主管是否阻止调用?,erlang,otp,erlang-supervisor,Erlang,Otp,Erlang Supervisor,我试图了解这里发生了什么: 我有一个主管,它在不触发MaxR,MaxT机制的情况下周期性地重新启动一个客户端。客户端崩溃的速度太慢,永远不会触发速率限制 还有另一种机制可以使用supervisor:which_children/1和delete_child/2,启动_children/2,以使子对象集适应现实(它扫描USB设备,试图在每个设备上找到一个supervisor子对象) 对于速率限制来说,这通常表现为一个安全网,但奇怪的是,似乎根本没有调用删除和启动孩子的机制 为了弄清楚发生了什么,我
MaxR,MaxT
机制的情况下周期性地重新启动一个客户端。客户端崩溃的速度太慢,永远不会触发速率限制
还有另一种机制可以使用supervisor:which_children/1
和delete_child/2,启动_children/2
,以使子对象集适应现实(它扫描USB设备,试图在每个设备上找到一个supervisor子对象)
对于速率限制来说,这通常表现为一个安全网,但奇怪的是,似乎根本没有调用删除和启动孩子的机制
为了弄清楚发生了什么,我从shell中调用了supervisor:which_children/1
,看起来这个调用只是阻塞了,永远不会返回
在主管忙于重新启动孩子时,是否会阻止对主管的呼叫
附录:
看起来崩溃发生在子系统启动期间:
=SUPERVISOR REPORT==== 29-Mar-2011::21:36:20 ===
Supervisor: {local,gateway_sup}
Context: start_error
Reason: {'EXIT',{timeout,{gen_server,call,[<0.155.0>,late_init]}}}
Offender: [{pid,<0.76.0>},
{name,gw_3_5},
{mfa,{channel,start_link,
[[{gateways,[{left,108},{right,103}]}],
{3,5}]}},
{restart_type,transient},
{shutdown,10000},
{child_type,worker}]
=主管报告===2011年3月29日::21:36:20===
主管:{local,gateway_sup}
上下文:启动错误
原因:{'EXIT',{timeout,{gen_server,call,[,late_init]}
罪犯:[{pid,},
{name,gw_3_5},
{mfa,{频道,启动链接,
[{网关,[{左,108},{右,103}]},
{3,5}]}},
{restart_type,transient},
{关闭,10000},
{child_type,worker}]
除了讨论之外,这个问题的答案是:
当重新启动一个在启动过程中失败的子进程时,supervisor在其进程(内部是gen_服务器)内循环,不处理对它的任何API调用
因此,如果将监控器的速率限制配置为不会触发子级的启动错误,则情况尤其糟糕。在我的示例中,我的启动速度很慢(尤其是出错时)
因此,如果主管总是循环尝试重新启动一个子系统,那么对它的任何调用都无法访问它。。。这通常是不好的。您是否在孩子的
start\u链接
功能中调用gen\u server:call
?是的。我需要在gen_服务器已经运行之后进行一些后期初始化。为什么不在init
函数中执行此操作?似乎这里可能存在死锁的风险…@Adam:late_init中的东西需要已经运行的gen_服务器(需要gen_服务器的pid)。我在这里看不到任何死锁的可能性(并且超时的原因是已知的)。你可以在这里看到代码,把你的问题放在一边,你应该能够在gen_server
进程中运行self()
,以获得它自己的pid。最好的办法是争取一个尽可能简单的初始化阶段,并在进程启动后完成其余的工作。这样做的好处有两方面,第一,监管者尽可能少地参与(并且不会被阻止,正如您所发现的,许多重新启动和较长的初始化阶段都是如此),第二,流程从一开始就受到监管者的保护(如果在以后的设置中出现问题,则由主管处理)。对此,我有过一些非常不愉快的经历,涉及复杂的init
回调(启动其他进程、读取文件等)。