2017-04-27 1 views
1

가정하자 나는 다음과 같은 설정을 가지고 :OTP에서 관리자의 하위 작업자를 시작할 때 추가 인수를 전달하는 방법은 무엇입니까?

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__, [3]) 
    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) 
iex> BranchSupervisor.start_worker 
# returns: 
{:error, 
{:EXIT, 
    {:undef, 
    [{TreeWorker, :start_link, [[2], 3], []}, 
    {:supervisor, :do_start_child_i, 3, [file: 'supervisor.erl', line: 359]}, 
    {:supervisor, :handle_call, 3, [file: 'supervisor.erl', line: 384]}, 
    {:gen_server, :try_handle_call, 4, [file: 'gen_server.erl', line: 629]}, 
    {:gen_server, :handle_msg, 5, [file: 'gen_server.erl', line: 661]}, 
    {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 240]}]}}} 

을 BranchSupervisor.start_worker? 나는 "3"을 제거하면 {_, wid} = Supervisor.start_child(__MODULE__, [3]) everyting works. 이것도 옳은 일입니까?

이것은 대부분 학습 연습입니다.

답변

3

여기 [3] 최종 인수 [[2]] ++ [3] =>[[2], 3] 올라서 [[2]]이다 BranchSupervisor.init/1worker에 전달 args에 부가되고있다. 목록이 두 요소 긴 때문에, 관리자는 TreeWorker.start_link([2], 3) 같은 TreeWorker.start_link/2를 호출되기 때문에이 같은 두 개의 인수를 허용하려는 경우, 당신은 단지 두 개의 인수 받아 start_link을 변경해야합니다 :이 동작이 설명되어 있습니다

defmodule TreeWorker do 
    def start_link(arg1, arg2) do 
    # `arg1 == [2]` and `arg2 == 3` here 
    ... 
    end 
end 

Supervisor.start_child/2에서 : :simple_one_for_one의 경우

, 정의 하위 규격은 관리자가 사용되는 대신 용어 child_spec 임의리스트 기대된다. 그러면 하위 프로세스는 자식 사양 의 기존 함수 인수에 주어진 목록을 추가하여 시작됩니다.

+1

감사합니다.이 유형의 자료는 일반적으로 문서에서 어딘가에 불려지나요? 나는 Supervisor.start_child를보고, 아마 늦은 시간 이후에 그것을 놓쳤습니다 ... – Nona

+1

예, Supervisor.start_child/2에 문서화되어 있습니다. 답변에 관련 인용문과 링크를 추가했습니다. – Dogbert

관련 문제