没有用于执行此操作的 API,因此我相信您会坚持使用升级方法,除非您想通过提交包含代码更改、新测试和文档的完整补丁的拉取请求向 OTP 团队提出新的 API变化。
还有一种非常肮脏的 hack 方法,它涉及操纵内部主管状态,因此我绝对不建议将其用于生产系统,但我认为它仍然很有趣。Asupervisor
将重启强度存储在其内部循环状态中。您可以通过调用sys:get_state/1,2
主管进程来查看此状态。例如,这是Yaws Web 服务器中主管的状态:
1> rr(supervisor).
[child,state]
2> sys:get_state(yaws_sup).
#state{name = {local,yaws_sup},
strategy = one_for_all,
children = [#child{pid = <0.67.0>,name = yaws_sup_restarts,
mfargs = {yaws_sup_restarts,start_link,[]},
restart_type = transient,shutdown = infinity,
child_type = supervisor,
modules = [yaws_sup_restarts]},
#child{pid = <0.42.0>,name = yaws_server,
mfargs = {yaws_server,start_link,
[{env,true,false,false,false,false,false,"default"}]},
restart_type = permanent,shutdown = 120000,
child_type = worker,
modules = [yaws_server]},
#child{pid = <0.39.0>,name = yaws_trace,
mfargs = {yaws_trace,start_link,[]},
restart_type = permanent,shutdown = 5000,
child_type = worker,
modules = [yaws_trace]},
#child{pid = <0.36.0>,name = yaws_log,
mfargs = {yaws_log,start_link,[]},
restart_type = permanent,shutdown = 5000,
child_type = worker,
modules = [yaws_log]}],
dynamics = undefined,intensity = 0,period = 1,restarts = [],
module = yaws_sup,args = []}
初始rr
命令从中检索记录定义,supervisor
因此当我们从 中获取状态时我们可以看到字段名称yaws_sup
,否则我们只会得到一个充满匿名值的元组。
在这种情况下,检索到的状态显示强度为 0。我们可以使用以下方法更改它sys:replace_state/2,3
:
3> sys:replace_state(yaws_sup, fun(S) -> S#state{intensity=2} end).
#state{name = {local,yaws_sup},
strategy = one_for_all,
children = [#child{pid = <0.67.0>,name = yaws_sup_restarts,
mfargs = {yaws_sup_restarts,start_link,[]},
restart_type = transient,shutdown = infinity,
child_type = supervisor,
modules = [yaws_sup_restarts]},
#child{pid = <0.42.0>,name = yaws_server,
mfargs = {yaws_server,start_link,
[{env,true,false,false,false,false,false,"default"}]},
restart_type = permanent,shutdown = 120000,
child_type = worker,
modules = [yaws_server]},
#child{pid = <0.39.0>,name = yaws_trace,
mfargs = {yaws_trace,start_link,[]},
restart_type = permanent,shutdown = 5000,
child_type = worker,
modules = [yaws_trace]},
#child{pid = <0.36.0>,name = yaws_log,
mfargs = {yaws_log,start_link,[]},
restart_type = permanent,shutdown = 5000,
child_type = worker,
modules = [yaws_log]}],
dynamics = undefined,intensity = 2,period = 1,restarts = [],
module = yaws_sup,args = []}
我们的第二个参数sys:replace_state/2
将状态记录作为参数并将其intensity
字段更改为 2。sys:replace_state/2,3
函数返回新状态,正如您在此处结果的末尾附近看到的那样,intensity
现在是 2 而不是 0。
正如sys:replace_state/2,3
文档所解释的,这些函数仅用于调试目的,因此我绝对不推荐在生产系统中使用它们来执行此操作。这里的第二个参数replace_state
表明,这种方法需要了解 的内部状态记录的详细信息supervisor
,我们在此处通过rr
shell 命令获得了这些信息,因此如果该记录发生更改,此代码可能会停止工作。更脆弱的是将supervisor
状态记录视为一个元组并指望intensity
字段位于特定的元组位置,以便您可以更改其值。因此,如果您真的想要更改主管重新启动强度的功能,从长远来看,您最好向 OTP 团队建议添加它;如果你打算走那条路,我建议首先在erlang-questions 邮件列表中提出这个想法以衡量兴趣。