Elixir:使用 Dynamic Supervisor 启动 child 的正确方法
Elixir : Correct way to start child using Dynamic Supervisor
我正在尝试创建一个动态主管来启动子进程。我使用三个模块来执行此操作,一个是主模块,第二个是动态管理器,第三个是 genserver。我没有收到任何错误,但我看不到任何子进程 运行.
这是我的代码。第一个是有 main 方法的模块
defmodule Simulator do
def main(args) do
{:ok, super_pid} = PersonManager.start_link(args)
num_of_persons = 1
start_persons(num_of_persons)
IO.inspect PersonManager.count_children, label: "The Persons started in main method are"
end
def start_persons(num_of_persons) when num_of_persons >=1 do
PersonManager.add_node(private_key, public_key, 0)
start_persons(num_of_persons-1)
end
# num_of_persons == 0 case handled
end
以下为动态Supervisor
defmodule PersonManager do
use DynamicSupervisor
def start_link(args) do
DynamicSupervisor.start_link(__MODULE__, :ok, name: __MODULE__)
end
def add_node(private_key, public_key, num_of_coins) do
# The code flow does come here, used inspect to check
child_spec = {Person, {private_key, public_key, num_of_coins}}
DynamicSupervisor.start_child(__MODULE__, child_spec)
#The code flow does come here, used inpect to check.
end
end
以下是工作人员应该创建的 GenServers
defmodule Person do
use GenServer
def init({private_key, public_key, address, num_of_coins}) do
IO.puts "Starting a person"
{:ok, %{private_key: private_key, public_key: public_key, num_of_coins: num_of_coins}}
end
def start_link({private_key, public_key, address, num_of_coins}) do
IO.puts "Starting a person"
GenServer.start_link(
__MODULE__,
{private_key, public_key, address, num_of_coins}
name: {:global, "node:#{public_key}"},
)
end
end
我希望 genserver 是 运行 但我得到 The Persons started in main method are: %{active: 0, specs: 0, supervisors: 0, workers: 0}
我不知道主管为什么不能启动genserver。
任何帮助都会很好。
TIA
对于您的情况,您需要做三件事:
在从 DynamicSupervisor
开始之前正确设置 child 规范:
child_spec = {Person, [private_key, public_key, num_of_coins]}
强制child开始失败,如果不成功:
case DynamicSupervisor.start_child do
{:ok, _pid} -> {}
{:error, {:already_started, _pid}} -> {}
error -> raise error
end
并且,确保 child 进程能够处理主管给它的确切参数:
defmodule Person do
use GenServer
def start_link([], private_key, public_key, num_of_coins) do
GenServer.start_link(
__MODULE__,
{private_key, public_key, num_of_coins},
name: {:global, "node:#{public_key}"}
)
end
def init({private_key, public_key, num_of_coins}) do
{:ok, %{private_key: private_key, public_key: public_key, num_of_coins: num_of_coins}}
end
end
我正在尝试创建一个动态主管来启动子进程。我使用三个模块来执行此操作,一个是主模块,第二个是动态管理器,第三个是 genserver。我没有收到任何错误,但我看不到任何子进程 运行.
这是我的代码。第一个是有 main 方法的模块
defmodule Simulator do
def main(args) do
{:ok, super_pid} = PersonManager.start_link(args)
num_of_persons = 1
start_persons(num_of_persons)
IO.inspect PersonManager.count_children, label: "The Persons started in main method are"
end
def start_persons(num_of_persons) when num_of_persons >=1 do
PersonManager.add_node(private_key, public_key, 0)
start_persons(num_of_persons-1)
end
# num_of_persons == 0 case handled
end
以下为动态Supervisor
defmodule PersonManager do
use DynamicSupervisor
def start_link(args) do
DynamicSupervisor.start_link(__MODULE__, :ok, name: __MODULE__)
end
def add_node(private_key, public_key, num_of_coins) do
# The code flow does come here, used inspect to check
child_spec = {Person, {private_key, public_key, num_of_coins}}
DynamicSupervisor.start_child(__MODULE__, child_spec)
#The code flow does come here, used inpect to check.
end
end
以下是工作人员应该创建的 GenServers
defmodule Person do
use GenServer
def init({private_key, public_key, address, num_of_coins}) do
IO.puts "Starting a person"
{:ok, %{private_key: private_key, public_key: public_key, num_of_coins: num_of_coins}}
end
def start_link({private_key, public_key, address, num_of_coins}) do
IO.puts "Starting a person"
GenServer.start_link(
__MODULE__,
{private_key, public_key, address, num_of_coins}
name: {:global, "node:#{public_key}"},
)
end
end
我希望 genserver 是 运行 但我得到 The Persons started in main method are: %{active: 0, specs: 0, supervisors: 0, workers: 0}
我不知道主管为什么不能启动genserver。 任何帮助都会很好。 TIA
对于您的情况,您需要做三件事:
在从 DynamicSupervisor
开始之前正确设置 child 规范:
child_spec = {Person, [private_key, public_key, num_of_coins]}
强制child开始失败,如果不成功:
case DynamicSupervisor.start_child do
{:ok, _pid} -> {}
{:error, {:already_started, _pid}} -> {}
error -> raise error
end
并且,确保 child 进程能够处理主管给它的确切参数:
defmodule Person do
use GenServer
def start_link([], private_key, public_key, num_of_coins) do
GenServer.start_link(
__MODULE__,
{private_key, public_key, num_of_coins},
name: {:global, "node:#{public_key}"}
)
end
def init({private_key, public_key, num_of_coins}) do
{:ok, %{private_key: private_key, public_key: public_key, num_of_coins: num_of_coins}}
end
end