worker 在 Supervisor 启动后退出

worker exits after starting in Supervisor

我正在尝试在我在 mix.exs

的应用程序模块中调用的 Supervisor 中启动以下工作人员

像这样

defmodule AppStarter do
import Supervisor.Spec
def start(_type,_args) do
    children=[
        worker(TPMod1,[],[]),
        worker(TPMod2,[],[])
    ]
    opts=[strategy: :one_for_one, name: HelloVisor]
    Supervisor.start_link(children,opts)
end


end

我的一个模块是 GenServer,另一个我保持了一个简单的监听过程。

defmodule TPMod1 do

def start_link() do
 IO.puts "started TPMod1"
 listen()
end



def listen() do
  receive do
    _ -> :ok
  end
  listen()
end

 def child_spec(opts) do
      %{
        id: __MODULE__,
        start: {__MODULE__, :start_link, []},
        type: :worker,
        restart: :permanent,
        shutdown: 500
      }
    end


end

问题是它卡住了,无法启动 worker 2 TPMod2 我在 TPMod1 中尝试过 start_link()

def start_link() do
 IO.puts "started TPMod1"
 Task.async(&listen/0)
end

但是那给我这个

** (Mix) Could not start application tproject: AppStarter.start(:normal, []) returned an error: shutdown: failed to start child: TPMod1 ** (EXIT) %Task{owner: #PID<0.143.0>, pid: #PID<0.144.0>, ref: #Reference<0.2187290957.3420192769.212288>}

我可以让它成为 GenServer 并让它工作,但我们如何启动一个简单的 worker?为什么主管不再重新启动它?不是无限但有时?它至少应该尝试重新启动并失败。如果有的话,也请提出其他改进建议。

主管期望 children 到 return {:ok, pid}:ignore{:error, reason}

它挂起是因为当 supervisor 在你的 worker 上运行 start_link 函数时,它执行(作为他自己),listen 设置了一个 receive 块,所以它卡在那里.当您使用 gen_* 模块的 start_link 和朋友时,它会负责产卵、return 正确等

在你的情况下你可以切换:

def start_link() do
 IO.puts "started TPMod1"
 listen()
end

至:

def start_link() do
 pid = spawn(__MODULE__, :listen, [])
 {:ok, pid}
end

这应该可以做到。