监督树无法启动 [英] Supervision tree failing to start

查看:68
本文介绍了监督树无法启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现此答案中所述的内容,但是我遇到了类似我自己的错误我在编译应用程序时将其包含在下面.

I'm trying to implement something like what is described in this answer, but I am getting errors like what I've included below when I compile the application.

** (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>

我不确定我是否天生就在做不允许做的事情,或者我犯了一个小错误.

I'm not sure if I am inherently doing something I'm not allowed to here, or I've just made a little mistake.

在某些情况下,这里是主管:

For some context here are the supervisors:

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

这是其中一名工人(他们看上去大体相同).

And here is one of the workers (they look largely the same).

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

推荐答案

在启动 Supervisor s的 Workers.Application 中,您将提供唯一的 id,但是它们还应该具有唯一的 name s.

In your Workers.Application when starting Supervisors, you'r providing unique ids, but they also should have unique names.

尝试添加另一个关键字,例如名称::"url_supervisor _#{i}" :

Try adding another keyword, something like name: :"url_supervisor_#{i}":

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

这篇关于监督树无法启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆