2017-04-14 8 views
2

this answer에 설명 된 것과 같은 것을 구현하려고하는데 응용 프로그램을 컴파일 할 때 아래에 포함 된 것과 같은 오류가 발생합니다.감독 트리가 시작되지 않음

** (Mix) Could not start application workers: Workers.Application.start(:normal, []) returned an error: shutdown: failed to start child: {Workers.UrlSupervisor, 2} 
    ** (EXIT) already started: #PID<0.1034.0> 

나는 본질적으로 내가 여기에 허락을받지 못했는지, 아니면 방금 약간의 실수를했는지 모르겠습니다. 여기

defmodule Workers.Application do 
    # See http://elixir-lang.org/docs/stable/elixir/Application.html 
    # for more information on OTP Applications 
    @moduledoc false 

    use Application 

    def start(_type, _args) do 
    import Supervisor.Spec, warn: false 

    url_workers = 1..100 |> Enum.map(fn (i) -> supervisor(Workers.UrlSupervisor, [i], [id: {Workers.UrlSupervisor, i}, restart: :temporary]) end) 
    domain_workers = 1..100 |> Enum.map(fn (i) -> supervisor(Workers.DomainSupervisor, [i], [id: {Workers.DomainSupervisor, i}, restart: :temporary]) end) 

    opts = [strategy: :one_for_one, name: Workers.Supervisor] 
    Supervisor.start_link(url_workers ++ domain_workers, opts) 
    end 
end 

defmodule Workers.UrlSupervisor do 
    def start_link(id) do 
    import Supervisor.Spec, warn: false 

    children = [worker(Task, [&Workers.Url.worker/0], [id: {Workers.Url, id}, restart: :permanent])] 

    opts = [strategy: :one_for_one, name: Workers.UrlSupervisor] 
    Supervisor.start_link(children, opts) 
    end 
end 

defmodule Workers.DomainSupervisor do 
    def start_link(id) do 
    import Supervisor.Spec, warn: false 

    children = [worker(Task, [&Workers.Domain.worker/0], [id: {Workers.Domain, id}, restart: :permanent])] 

    opts = [strategy: :one_for_one, name: Workers.DomainSupervisor] 
    Supervisor.start_link(children, opts) 
    end 
end 

그리고 노동자 중 하나입니다 (그들은 거의 같은 모양) : 여기에 몇 가지 상황에 대한

는 감독이다. 당신의 Workers.Application에서

defmodule Workers.Domain do 
    def worker do 
    case Store.Domains.pop do 
     :empty -> 
     IO.puts "[Domain] none found, waiting..." 
     :timer.sleep(1000) 
     {crawl_id, domain} -> 
     IO.puts "[Domains] found a domain to check: #{domain}" 
     case Core.check_domain(domain) do 
      :error -> 
      Utils.insert(crawl_id, domain, false) 
      :registered -> 
      Utils.insert(crawl_id, domain, false) 
      :available -> 
      Utils.insert(crawl_id, domain, true) 
     end 
    end 
    worker() 
    end 
end 
+3

,하지만 그들은 또한 독특한이 있어야합니다 :"url_supervisor_#{i}"를 이름. 'name :: : url_supervisor _ # {i}' '와 같은 다른 키워드를 추가 할 수 있습니까? 도메인 감독자와 비슷한 기능이 있습니까? –

+0

완전히 고쳐, 나를 바보 같은 실수! 이것을 대답으로 만들면 받아 들일 것입니다. :) – Zen

+1

완료. 도와 줘서 기뻐요! –

답변

2

Supervisor들 시작할 때 you'r 고유 id의를 제공하지만, 또한 독특한 name의이 있어야합니다.

시도, 이름이 같은 다른 키워드를 추가 : 시작할 때 당신은`Workers.Application`는`Supervisor`s, 당신의 고유`id`s를 제공

def start(_type, _args) do 
    import Supervisor.Spec, warn: false 

    url_workers = 1..100 |> Enum.map(fn (i) -> 
    supervisor(Workers.UrlSupervisor, [i], 
       [id: {Workers.UrlSupervisor, i}, 
       name: :"url_supervisor_#{i}", # Name added here 
       restart: :temporary]) 
    end) 
    domain_workers = 1..100 |> Enum.map(fn (i) -> 
    supervisor(Workers.DomainSupervisor, [i], 
       [id: {Workers.DomainSupervisor, i}, 
       name: :"domain_supervisor_#{i}", # Name added here 
       restart: :temporary]) 
    end) 

    opts = [strategy: :one_for_one, name: Workers.Supervisor] 
    Supervisor.start_link(url_workers ++ domain_workers, opts) 
end