Elixir 我应该使用哪种OTP行为来处理“问题”;“无止境”;重复任务?

Elixir 我应该使用哪种OTP行为来处理“问题”;“无止境”;重复任务?,elixir,otp,phoenix-framework,Elixir,Otp,Phoenix Framework,我想在Phoenix应用程序旁边反复运行相同的操作序列(当然,如果worker出现故障,不会导致整个web应用程序崩溃),但我真的不知道我应该使用GenServer、Elixir的任务、代理还是完全不同的东西,我到目前为止还没有想到 当我启动Phoenix应用程序时,工作程序也应该启动,它会定期提取串行连接的一些值,通过Phoenix频道进行广播,收集这些值,直到达到@save_interval,然后计算中值,通过其他频道广播该中值并将其写入XDB。现在我有这样的工作: def do_your_

我想在Phoenix应用程序旁边反复运行相同的操作序列(当然,如果worker出现故障,不会导致整个web应用程序崩溃),但我真的不知道我应该使用GenServer、Elixir的任务、代理还是完全不同的东西,我到目前为止还没有想到

当我启动Phoenix应用程序时,工作程序也应该启动,它会定期提取串行连接的一些值,通过Phoenix频道进行广播,收集这些值,直到达到
@save_interval
,然后计算中值,通过其他频道广播该中值并将其写入XDB。现在我有这样的工作:

def do_your_thing(serial_pid) do
  Stream.interval(@interval_live)
    |> get_new_values_from_serial(serial_pid)
    |> broadcast!("live-channel:#{@name}")
    |> Enum.take(div(@interval_save, @interval_live))
    |> calculate_medians()
    |> broadcast!("update-channel:#{@name}")
    |> write_to_database()

  do_your_thing(serial_pid) # repeat
end

我只是开始弄清楚所有OTP的东西,希望你们中的某个人能帮我找到正确的方向。

你应该使用一个GenServer,它在x秒后(在下面的示例中为60秒)发送消息:


为什么不在无限循环中周期性地执行任务(可能由Stream.interval或Stream.repeative提供动力)?如果这只是一个周期性的拉取,将拉取的数据进一步转发到系统,那么它实际上不需要是GenServer,对吗。任务仍然是OTP兼容的,对我来说,这项工作似乎更简单。原因是任务无法接收系统消息。我们想让流和朋友知道这些,但它不在1.0中,可能只在1.3中。此外,您可能希望您的主管能够重新启动工人进行定期工作,而不仅仅是让无限流在出现问题时破坏当前进程。@JoséValim在Elixir中有更好的方法吗1.3?谢谢Jose!我很高兴能从尽可能好的来源看到这个问题的答案。
defmodule MyApp.Worker do
  use GenServer

  def start_link() do
    GenServer.start_link(__MODULE__, [])
  end

  def init([]) do
    schedule_work()
    {:ok, []}
  end

  def handle_info(:work, state) do
    state = do_work(state)
    schedule_work()
    {:noreply, state}
  end

  defp do_work(state) do
    # Do your work here and return state
  end

  defp schedule_work do
    Process.send_after(self(), :work, 60_000)
  end
end