【问题标题】:How Can I Dynamically Create Genservers in Elixir?如何在 Elixir 中动态创建 Genserver?
【发布时间】:2019-01-02 12:39:29
【问题描述】:

我需要创建进程运行时,以保持不同的状态。 我的 :config 中有一个用户列表,例如:

config :backend,
 users: [user1, user2, user3]

是否可以循环浏览此列表并为每个人创建一个受监管的 Agent 或 Genserver?

【问题讨论】:

  • 是的,这确实是可能的。 旁注:您发布的内容不是有效的 Elixir。

标签: elixir phoenix-framework gen-server


【解决方案1】:

假设confix.exs中的代码是正确的

config :backend,
  users: ~w[user1 user2 user3]

要动态启动受监督的孩子,您可以使用 e. G。 DynamicSupervisor.

在您的静态初始化代码中,您开始 DynamicSupervisor 没有任何子:

children = [
  ...,
  {DynamicSupervisor, strategy: :one_for_one, name: MyApp.DS}
]
Supervisor.start_link(children, strategy: :one_for_one)

当你想动态启动子进程时,你基本上是这样做的:

users = Application.get_env(:backend, :users, [])
agents =
  Enum.map(users, fn user ->
    with {:ok, agent} <- DynamicSupervisor.start_child(MyApp.DS, {Agent, fn -> %{} end}) do
      Agent.update(agent, &Map.put(&1, :user, user))
    end
  end)

【讨论】:

  • 非常感谢。顺便说一句,代理在算术异常时终止,而不重新启动,就像他们没有受到监督一样。
  • 没办法。我很肯定使用上面的代码DynamicSupervisor 会在终止时重新启动代理。
  • 我的错,我再次查看日志,在前一个终止后,我可以看到“客户端#PID 处于活动状态”。问题是现在我无法使用代理再次访问它(当我手动启动前一个时,来自模式匹配 {:ok, agent} )。我需要给这些代理一个名字,但如果它们重新启动,我需要用相同的名字访问它们
  • 这超出了这个问题的范围。给代理命名,或使用child_spec 使用DynamicSupervisor.which_children/1 查找代理,有很多方法可以通过名称而不是PID 来引用进程。
猜你喜欢
  • 2019-10-09
  • 2017-10-29
  • 2018-12-14
  • 1970-01-01
  • 2015-01-17
  • 2017-10-16
  • 2019-11-28
  • 2021-03-16
  • 1970-01-01
相关资源
最近更新 更多