在Elixir中,使用simple_one_for_one supervisor和start_child,如何在主管中设置子ID?

时间:2016-10-12 17:46:44

标签: elixir otp

这是一个简单的测试主管:

defmodule SupervisorTest.Worker.Supervisor do
  use Supervisor

  def start_link do
    Supervisor.start_link(__MODULE__, :ok, name: __MODULE__)
  end

  def start_worker(args) do
    Supervisor.start_child(__MODULE__, [args])
  end

  def init(:ok) do
    children = [
      worker(SupervisorTest.Worker, [])
    ]

    supervise(children, strategy: :simple_one_for_one)
  end
end

这是我更简单的工人:

defmodule SupervisorTest.Worker do
  use GenServer

  def start_link(args) do
    GenServer.start_link(__MODULE__, args)
  end

  def state(pid) do
    GenServer.call(pid, :state)
  end

  def stop(pid) do
    GenServer.stop(pid, :normal)
  end

  def handle_call(:state, _from, state) do
    {:reply, state, state}
  end
end

理想情况下,我希望能够使用此主管调用Supervisor.which_children并获取子元组列表,ID为生成的UUID。看起来我无法在init worker语句中设置它。并且没有start_child/3可以选择。而且我无法使用另一个start_child/2语句的输出调用worker ...所以我看不到任何方法可以将ID设置为某些内容......任何想法?

编写此代码时,当我调用Supervisor.which_children时,每个子元组的第一个元素是:undefined

2 个答案:

答案 0 :(得分:2)

根据Supervisor.which_children/1superviser:which_children/1的文档,:simple_one_for_one主管无法做到这一点:

  

id - 如子规范中所定义,或:undefined主管<{1}}

  

simple_one_for_one - 如子规范中所定义,或Id主管undefined

因此,对于simple_one_for_one主管,返回元组的第一项始终为simple_one_for_one

答案 1 :(得分:1)

您可以在

中生成UUID
def start_worker(args) do
  uuid = <generate UUID>,
  Supervisor.start_child(__MODULE__, [args, uuid])
end

在工人方面:

def start_link(args, uuid) do
  GenServer.start_link(__MODULE__, [args, uuid])
end

def init([args,uuid]) do
  {:ok, #State{ uuid: uuid }}
end

这样当你获取who_children时,你可以通过他们的pid查询孩子的UUID。