关于otp:Elixir:invalid_child_spec用于受监督的进程。不知道为什么

Elixir :invalid_child_spec for supervised process. Can't figure out why

我正在首次实施主管,但遇到了一些我无法从文档中找到的问题。具体来说,当我尝试使用SlowRamp.flood开始我的过程时,我得到了{:error, {:invalid_child_spec, []}}

这是一个非常简单的应用程序,使用混合新的slow_ramp --sup制成。

./lib/slow_ramp.ex中的主文件为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
defmodule SlowRamp do
  use Application

  # See http://elixir-lang.org/docs/stable/elixir/Application.html
  # for more information on OTP Applications
  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      worker(SlowRamp.Flood, [])
    ]

    # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, name: SlowRamp.Supervisor]
    Supervisor.start_link(children, opts)
  end

  def flood do
    Supervisor.start_child(SlowRamp.Supervisor, [])
  end
end

我的子函数/文件在./lib/SlowRamp/flood.ex中,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
defmodule SlowRamp.Flood do
  def start_link do
    Task.start_link(fn -> start end)
  end

  defp start do
    receive do
      {:start, host, caller} ->
        send caller, System.cmd("cmd", ["opt"])
    end
  end
end

任何帮助将不胜感激。谢谢!


问题已解决

1
Supervisor.start_child(SlowRamp.Supervisor, [])

您需要有效的子规范,例如:

1
2
3
4
def flood do
  import Supervisor.Spec
  Supervisor.start_child(SlowRamp.Supervisor, worker(SlowRamp.Flood, [], [id: :foo]))
end

这就是其说明子规范无效的原因


从elixir 1.5开始,您现在还可以定义child_spec来解决此问题。

SlowRamp.Flood内,添加如下函数:

1
2
3
4
5
6
7
8
9
10
defmodule SlowRamp.Flood do
  def child_spec(arg) do
    %{
     id: __MODULE__,
     start: {__MODULE__, :start_link, [arg]},
     type: :worker
   }
  end
  # Rest of your code here
end

然后,您现有的start_link应该可以使用。