Elixir 工人在主管启动后退出
我正在尝试在mix.exs中调用应用程序模块的主管中启动以下工作人员 像这样Elixir 工人在主管启动后退出,elixir,gen-server,erlang-supervisor,Elixir,Gen Server,Erlang Supervisor,我正在尝试在mix.exs中调用应用程序模块的主管中启动以下工作人员 像这样 defmodule AppStarter do import Supervisor.Spec def start(_type,_args) do children=[ worker(TPMod1,[],[]), worker(TPMod2,[],[]) ] opts=[strategy: :one_for_one, name: HelloVisor] Su
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 2TPMod2
我在TPMod1
的start\u link()中尝试过
但这给了我这个
**(Mix)无法启动应用程序tproject:AppStarter。启动(:normal,[])返回错误:关机:无法启动
启动子项:TPMod1
**(退出)%Task{owner:#PID,PID:#PID,ref:#Reference}
我可以让它成为GenServer,让它工作,但我们如何才能开始一个简单的工人?为什么主管不重新启动它?不是无限,而是有时?它至少应该尝试重新启动并失败。如果有其他改进,请提出建议。主管希望孩子们返回{:ok,pid}
,:ignore
或{:error,reason}
它挂起是因为当主管在您的工作人员上运行start\u link
函数时,它会(像他自己一样)执行listen
,这会设置一个receive
块,因此它会卡在那里。当您使用gen_*模块的start_链接
和friends时,它负责生成、正确返回等
在您的情况下,您可以切换:
def start_link() do
IO.puts "started TPMod1"
listen()
end
致:
这样就可以了。酷!因此,始终使用gen_u*而不是简单的繁殖和返回是一种良好的做法吗?@YugandharChaudhari我认为在99%的常规情况下,没有理由不使用现有的OTP行为,因为它满足了主管等的期望,而对于原始流程,如果你想成为OTP,就必须实施这些行为。有时gen_服务器太多(但任何有点结构的进程都很适合),您可以使用类似于任务的东西(通过不同的模式,如async_nolink等)很好地适应其他OTP行为,例如gen_服务器,可以从内部生成,也可以从外部等待,等等。这当然取决于……酷!因此,始终使用gen_*[行为]而不是简单的繁殖和返回,这是一种好的做法吗?--这不仅仅是良好的实践,也是唯一的实践。有一次,我试图弄清楚如何使用主管启动任意进程,在erlang中进行了大量的挖掘,终于弄清楚不能使用主管启动任意进程。主管期望其启动的流程是OTP应用程序
,…。这意味着工作人员必须定义某些功能,并且这些功能必须返回主管期望的某些值…这就是主管能够与工作人员通信的方式。这里有一些更多的信息:另外:Supervisor.Spec——此模块已弃用。改用“主管”模块中概述的新子规范。
def start_link() do
IO.puts "started TPMod1"
listen()
end
def start_link() do
pid = spawn(__MODULE__, :listen, [])
{:ok, pid}
end