Elixir:让演员循环重新运行

时间:2017-09-17 06:35:29

标签: elixir gen-server

我正在制作一个主工作者应用程序。主代码如下。此代码start_link中异步调用worker 。一旦工人完成了他们的工作,他们就会使用handle_cast异步调用向主人报告。在此之后,我打算让主演员' ON' ,以便它可以重新生成新的工作人员Actors(就像它在第一次start_link调用中所做的那样)。但是,一旦所有工人演员完成他们的工作,主人就会停止。此stackoverflow帖子提到使用递归调用,但我无法使用Genserver执行此操作。 Genserver中是否有任何方法可以实现它?

defmodule Bitcoin.MasterNode do
use GenServer

def start_link(opts) do
    {:ok, pid} = GenServer.start_link(__MODULE__,:ok, opts)
    start_workers(----perform some task asynchronously----)
    {:ok, pid}
end

def set_message(server, name) do
    GenServer.cast(server, {:set_message, name})
end

#callbacks
def init(:ok) do
    names = []
    {:ok, names}
end

def handle_cast({:set_message, name},names) do
    names = names ++ name
    IO.puts name
    {:noreply,names}
end

编辑:我在分布式模式下运行应用程序,即master也连接到外部工作程序节点。如果Master死了,连接也会消失。目的是使主节点保持相同的PID运行无限次。

1 个答案:

答案 0 :(得分:2)

如果我理解你的意图,你想在所有孩子完成后立即重启整个过程。如果这是真的,那么应该使用OTP功能而不是发明自己的轮子:)

只需使用另一位主管扩展监督树,即监督您的“主人”(Bitcoin.MasterNode,)和您已完成

会发生什么:

  1. MasterSupervisor开始;
  2. MasterSupervisor:one_for_one策略透明地启动MasterNode;
  3. MasterNode的行为与现在完全相同;
  4. 一旦所有工人完成,MasterNode 去世,这很好;
  5. 一旦孩子MasterNode已经死亡,MasterSupervisor 会因为策略而自动重启
  6. 要跟踪GenServer是否已重生,请使用named servers而不是仅仅PID

    GenServer.start_link(__MODULE__,:ok, name: MyWorker)