DynamicSupervisor 的孩子——长时间运行的作业

问题描述 投票:0回答:2

假设我有一个简单的模块

defmodule MyWorker do
  def do_long_running_work(a, b, c) do
    # ......
  end
end

和 DynamicSupervisor

defmodule MyDynamicSupervisor do
  use DynamicSupervisor

  def start_link(_arg) do
    DynamicSupervisor.start_link(__MODULE__, :ok, name: __MODULE__)
  end

  def init(:ok) do
    DynamicSupervisor.init(strategy: :one_for_one)
  end

  def add_my_worker(worker_name, game_id) do
    child_spec = {MyWorker, {worker_name, game_id}}
    DynamicSupervisor.start_child(__MODULE__, child_spec)
  end

  def remove_my_worker(worker_pid) do
    DynamicSupervisor.terminate_child(__MODULE__, worker_pid)
  end

  def children do
    DynamicSupervisor.which_children(__MODULE__)
  end

  def count_children do
    DynamicSupervisor.count_children(__MODULE__)
  end
end

文档说

MyWorker
必须有一个
start_link
方法。此外,那里的例子表明
MyWorker
GenServer
。尽管它也可以包含
child_spec
而不必
use GenServer

但是,

MyWorker
会在 do_long_running_work() 中做一项
long-running
的工作——可能持续数小时的工作。而
GenServer
本身并不意味着运行长时间运行的作业,对吗?

那我怎么去跑步

MyWorker
呢?
MyWorker
的简单实现会是什么样子?

在我的情况下,

start_link
看起来不是
GenServer
是什么?


还有数以千计的

MyWorker
实例创建并运行 vis
MyDynamicSupervisor
.

erlang elixir background-process erlang-supervisor
2个回答
0
投票

长期运行的工作最好由[监督]支持

Task
.

此外,不需要

DynamicSupervisor
Task.Supervisor
就足够了。


0
投票

文档说 MyWorker 必须有一个 start_link 方法。此外,那里的例子表明 MyWorker 是 GenServer.

没有。

child specification
告诉 DynamicSupervisor 如何启动孩子:

子规范是一张最多包含6个元素的地图。这 以下列表中的前两个键是必需的,其余的 那些是可选的:

:id - 用于在内部标识子规范的任何术语 主管;默认为给定的模块。此密钥是必需的。 对于主管,如果 :id 值冲突,主管 将拒绝初始化并需要明确的 ID。这不是 不过动态主管的案例。

:start - 一个包含要调用的模块函数参数的元组以启动 子进程。这个密钥是必需的。

https://hexdocs.pm/elixir/1.14.4/Supervisor.html#module-child-specification

例如:

  def add_my_worker(worker_module_name, 
                    worker_function_name, 
                    list_of_worker_function_args, 
                    game_id) do
    child_spec = %{
          id: game_id,
          start: {worker_module_name, worker_function_name, list_of_worker_function_args}
    }
    DynamicSupervisor.start_child(__MODULE__, child_spec)
  end

你可以这样调用

add_my_worker()

add_my_worker(MyWorker, 
              :do_long_running_work, 
              [10, :abc, "hello"],
              23561)

DynamicSupervisor 然后会调用:

spawn_link(MyWorker, :do_long_running_work, [10, :abc, "hello"]) 
© www.soinside.com 2019 - 2024. All rights reserved.