为什么这个 child 进程在我启动它的 parent 时没有启动?
Why doesn't this child process get started when I start its parent?
假设我有以下主管树设置,其中一个 parent 开始 child 并且 child 开始它的 grandchild:
defmodule NestedSupervisorTree do
# this will be the top line supervisor
use Supervisor
def start_link, do: Supervisor.start_link(__MODULE__, :ok, name: __MODULE__)
def init(:ok) do
children = [
supervisor(BranchSupervisor, [], restart: :temporary)
#worker(TreeWorker, [], restart: :temporary)
]
supervise(children, strategy: :simple_one_for_one)
end
def start_branch(args) do
{_, branch_id} = Supervisor.start_child(__MODULE__, [args])
end
end
defmodule BranchSupervisor do
# this will be the top line supervisor
use Supervisor
def start_link(args), do: Supervisor.start_link(__MODULE__, [args], name: __MODULE__)
def init(args) do
IO.puts "branch init args:"
IO.inspect args
children = [
worker(TreeWorker, [args], restart: :temporary)
]
supervise(children, strategy: :simple_one_for_one)
end
def start_worker do
{_, wid} = Supervisor.start_child(__MODULE__, [])
end
end
defmodule TreeWorker do
def start_link(args) do
IO.puts "worker args:"
IO.inspect args
#IO.puts String.codepoints raw
{:ok, spawn(fn -> loop end)}
end
def loop do
receive do
:stop -> :ok
msg ->
IO.inspect msg
loop
end
end
end
假设我在 iex 终端中按以下顺序发出以下命令:
iex> {_, pid} = NestedSupervisorTree.start_link
iex> {_, cid} = NestedSupervisorTree.start_branch(2)
为什么 BranchSupervisor 的 grandchild 没有启动?当我执行 Supervisor.which_children(cid) 时,我得到一个空列表...我认为 BranchSupervisor#init 在调用 NestedSupervisorTree.start_branch( 2) 后跟 NestedSupervisorTree#start_link。我还认为 BranchSupervisor#init 末尾的监督启动了 children...?或者它只是告诉你哪个 "type of children" BranchSupervisor 可以监督和 "strategy" 监督他们?
当您将 strategy
设置为 :simple_one_for_one
时,Supervisor 不会自动启动任何 child。它接受 children 列表中的一项作为稍后调用 start_child
时的模板。如果您想启动 child 进程,您需要自己调用 start_child
。如果您只想启动一个 child 并且希望它自动完成,您可能正在寻找 :one_for_one
策略。
:simple_one_for_one
- similar to :one_for_one
but suits better when dynamically attaching children. This strategy requires the supervisor specification to contain only one child. Many functions in this module behave slightly differently when this strategy is used.
和
the simple one for one specification can define only one child which works as a template for when we call start_child/2
假设我有以下主管树设置,其中一个 parent 开始 child 并且 child 开始它的 grandchild:
defmodule NestedSupervisorTree do
# this will be the top line supervisor
use Supervisor
def start_link, do: Supervisor.start_link(__MODULE__, :ok, name: __MODULE__)
def init(:ok) do
children = [
supervisor(BranchSupervisor, [], restart: :temporary)
#worker(TreeWorker, [], restart: :temporary)
]
supervise(children, strategy: :simple_one_for_one)
end
def start_branch(args) do
{_, branch_id} = Supervisor.start_child(__MODULE__, [args])
end
end
defmodule BranchSupervisor do
# this will be the top line supervisor
use Supervisor
def start_link(args), do: Supervisor.start_link(__MODULE__, [args], name: __MODULE__)
def init(args) do
IO.puts "branch init args:"
IO.inspect args
children = [
worker(TreeWorker, [args], restart: :temporary)
]
supervise(children, strategy: :simple_one_for_one)
end
def start_worker do
{_, wid} = Supervisor.start_child(__MODULE__, [])
end
end
defmodule TreeWorker do
def start_link(args) do
IO.puts "worker args:"
IO.inspect args
#IO.puts String.codepoints raw
{:ok, spawn(fn -> loop end)}
end
def loop do
receive do
:stop -> :ok
msg ->
IO.inspect msg
loop
end
end
end
假设我在 iex 终端中按以下顺序发出以下命令:
iex> {_, pid} = NestedSupervisorTree.start_link
iex> {_, cid} = NestedSupervisorTree.start_branch(2)
为什么 BranchSupervisor 的 grandchild 没有启动?当我执行 Supervisor.which_children(cid) 时,我得到一个空列表...我认为 BranchSupervisor#init 在调用 NestedSupervisorTree.start_branch( 2) 后跟 NestedSupervisorTree#start_link。我还认为 BranchSupervisor#init 末尾的监督启动了 children...?或者它只是告诉你哪个 "type of children" BranchSupervisor 可以监督和 "strategy" 监督他们?
当您将 strategy
设置为 :simple_one_for_one
时,Supervisor 不会自动启动任何 child。它接受 children 列表中的一项作为稍后调用 start_child
时的模板。如果您想启动 child 进程,您需要自己调用 start_child
。如果您只想启动一个 child 并且希望它自动完成,您可能正在寻找 :one_for_one
策略。
:simple_one_for_one
- similar to:one_for_one
but suits better when dynamically attaching children. This strategy requires the supervisor specification to contain only one child. Many functions in this module behave slightly differently when this strategy is used.
和
the simple one for one specification can define only one child which works as a template for when we call
start_child/2