如何解决DynamicSupervisors的工作人员姓名
大家好,
我对Elixir有点陌生,并且在为Elixir中的工人设置工人名称和ID时非常迷失了,我希望有人能对我有所帮助。
我的申请文件
defmodule Squareup.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false
use Application
def start(_type,_args) do
children = [
# Starts a worker by calling: Squareup.Worker.start_link(arg)
# {Squareup.Worker,arg}
Journey,Squareup.JourneySupervisor,{Squareup.DynamicJourneySupervisor,strategy: :one_for_one,name: Squareup.DynamicJourneySupervisor}
]
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one,name: Squareup.Supervisor]
Supervisor.start_link(children,opts)
end
end
因此,我启动了2个主管,一个是常规主管,另一个是动态主管:
常规的:
defmodule Squareup.JourneySupervisor do
use Supervisor
def start_link(opts) do
Supervisor.start_link(__MODULE__,opts,name: :my_test_123)
end
@impl true
def init(_init_arg) do
children = [
# Starts a worker by calling: Squareup.Worker.start_link(arg)
# {Squareup.Worker,arg}
{Queue,[:child_one]},{Queue,[:child_two]},]
Supervisor.init(children,strategy: :one_for_one)
end
def child_spec(opts) do
%{
id: :my_test_123s,start: {__MODULE__,:start_link,[opts]},shutdown: 5_000,restart: :permanent,type: :supervisor
}
end
end
动态一:
defmodule Squareup.DynamicJourneySupervisor do
use DynamicSupervisor
def start_link(init_arg) do
DynamicSupervisor.start_link(__MODULE__,init_arg,name: __MODULE__)
end
def start_child(init_args) do
# If MyWorker is not using the new child specs,we need to pass a map:
# spec = %{id: MyWorker,start: {MyWorker,[foo,bar,baz]}}
spec = {Queue,init_args}
DynamicSupervisor.start_child(__MODULE__,spec)
end
@impl true
def init(init_arg) do
DynamicSupervisor.init(strategy: :one_for_one)
end
end
普通主管一个名为Queue
defmodule Queue do
require Logger
use GenServer
### GenServer API
def init(state),do: {:ok,state}
def handle_call(:dequeue,_from,[value | state]) do {:reply,value,state} end
def handle_call(:dequeue,[]),do: {:reply,nil,[]}
def handle_call(:queue,state),state,state}
def handle_cast({:enqueue,value},state) do {:noreply,state ++ [value]} end
### Client API / Helper functions
def start_link(state \\ []) do
Logger.info("Initializing queue with state:")
Logger.info(inspect(state))
GenServer.start_link(__MODULE__,name: List.first(state))
end
def child_spec(opts) do
Logger.info("Initializing child_spec:")
Logger.info(inspect(opts))
%{
id: List.first(opts),type: :worker
}
end
def queue,do: GenServer.call(__MODULE__,:queue)
def enqueue(value),do: GenServer.cast(__MODULE__,{:enqueue,value})
def dequeue,:dequeue)
end
启动应用程序时,我会这样:
12:55:45.744 [info] Initializing child_spec:
12:55:45.749 [info] [:child_one]
12:55:45.749 [info] Initializing child_spec:
12:55:45.749 [info] [:child_two]
12:55:45.749 [info] Initializing queue with state:
12:55:45.749 [info] [:child_one]
12:55:45.749 [info] Initializing queue with state:
12:55:45.749 [info] [:child_two]
iex(4)> Supervisor.which_children(:my_test_123)
[
{:child_two,#PID<0.218.0>,:worker,[Queue]},{:child_one,#PID<0.217.0>,[Queue]}
]
但是当我告诉Dynamic Supervisor启动该过程
Squareup.DynamicJourneySupervisor.start_child([:my_dyname])
12:56:07.329 [info] Initializing child_spec:
12:56:07.329 [info] [:my_dyname]
12:56:07.330 [info] Initializing queue with state:
12:56:07.330 [info] [:my_dyname]
查找工作人员名称,然后它们总是:undefined
iex(5)> Supervisor.which_children(Squareup.DynamicJourneySupervisor)
[{:undefined,#PID<0.224.0>,[Queue]}]
工作人员的ID似乎设置正确。通过DynamicSupervisor启动进程时,是否可以设置名称?
已经非常感谢!
利昂
解决方法
似乎您只是误解了which_children/1
函数的返回值。它返回一个列表,其中包含有关所有实际孩子的信息。
来自docs:
* id - it is always :undefined for dynamic supervisors
因此,您实际上是在正确命名进程。仅Queue
模块的客户代码不正确。如果您要访问功能queue
enqueue
和dequeue
,则应对其进行实际调用,以实际调用命名的GenServer。
我的意思是他们应该看起来像这样:
def queue(name \\ __MODULE__),do: GenServer.call(name,:queue)
def enqueue(name \\ __MODULE__,value),do: GenServer.cast(name,{:enqueue,value})
def dequeue(name \\ __MODULE__),:dequeue)
这样GenServer.call/2
将始终调用命名的GenServer。您也可以不按名称访问它们,而按其pids
访问(实际上您可以根据需要从which_children/1
函数动态访问它们)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。