Erlang/OTP Supervisor : one-for-one and simple-one-for-one
Supervisor 的四个 Restart Strategy 中,关于 one for one 和 simple one for one , 虽然很多地方都说 simple one for one 是 one for one 的简化版,但两者之间还是有一些不同。
1. 先来看一个简单的 one for one 和 simple one for one 的例子
one for one
init(_Args) -> {ok, {{one_for_one, 1, 60}, [{call, {call, start_link, []}, permanent, brutal_kill, worker, [call]}]}}.
- simple one for one
init(_Args) -> {ok, {{simple_one_for_one, 0, 1}, [{call, {call, start_link, []}, permanent, brutal_kill, worker, [call]}]}}.
初始化方法非常相似
2. 启动 Supervisor
- one for one
启动时,会同时启动一个子进程 - simple one for one
启动时,supervisor 并不会启动任何子进程,所有的子进程都是通过supervisor:start_child(Sup, List)
来动态添加的
3. 允许的 Child Type
- one for one
允许不同的 child type,所以每次添加子进程都需要传递完整的 child spec - simple one for one
只能有一个 child type,不同的 child instance 可以共享同一个 child spec
4. 添加子进程
one for one
添加子进程的时候传递的是子进程规格supervisor:start_child(Sup, ChildSpec)
simple one for one
添加子进程的时候传递的是任意的值列表,它将会被添加到子进程规格中的参数列表中,即实际上是通过apply(call, start_link, [] ++ List)
来启动的supervisor:start_child(Sup, List)
相同的是,如果 supervisor 挂了,并且被 restart,之前动态添加的子进程将会全部丢失
5. Supervisor 停止
- one for one
按照启动 Spec 相反的顺序停止所有子进程,然后停止自身 - simple one for one
由于 supervisor 启动的是同一子进程的多个 instance,因此在停止的时候不存在顺序,
在定义 Shutdown Strategy 的时候应该注意其 terminate 表现的区别。