【问题标题】:How to create an event emitter with elixir, the otp way如何用elixir创建事件发射器,otp方式
【发布时间】:2015-10-03 07:14:49
【问题描述】:

在 elixir 中创建在每个给定时间滴答的前台进程的最佳方法是什么?

我的主要问题是这样的方法:

defmoulde Ticker do
  def tick do
    do_something()
    :timer.sleep(1000)
    tick
  end
end

有效,但设计错误。它绝对不是每秒都在滴答作响,而是每秒加上 do_something() 完成的时间。 我可以生成一个进程来处理“某事”,但仍然有一点滞后。

另外,我正在尝试构建一个混合应用程序,其中涉及一些 GenServer,以及一个应该每 x 秒调用一次服务器的主前台进程(我在这里问的那个)。有没有 otp 方法可以做到这一点?

【问题讨论】:

    标签: elixir erlang-otp eventemitter


    【解决方案1】:

    如果您更喜欢发送消息而不是在给定的时间间隔调用函数,您可以使用:timer.send_interval/3

    例如如果您想像 OP 在他们的回答中提到的那样每秒向GenServer 发送一条消息,您可以执行以下操作:

    :timer.send_interval(:timer.seconds(1), target_pid, :tick)
    

    其中target_pid 是您要向其发送消息的GenServer 的PID。然后你可以像这样在GenServer 中处理这条消息:

    def handle_info(:tick, state) do
      do_something()
      {:noreply, state}
    end
    

    【讨论】:

      【解决方案2】:

      我认为timer:apply_interval/4 应该适合您的需求。它是这样使用的:

      defmodule Tick do
        def tick do
          IO.inspect(:tick)
        end
      end
      
      :timer.apply_interval(:timer.seconds(1), Tick, :tick, [])
      

      依次是间隔、模块名称、要调用的函数和调用它的参数。然后您可以在该函数内向您的GenServers 发送消息。在此处查看完整文档:apply_interval/4

      要考虑的另一件事是,如果您的 tick 函数只是向某些 GenServers 发送简单的消息,那么它可能非常快,所以你的实现可能没问题,一旦包裹在Task 并插入监督树(如果您不关心潜在的轻微漂移)。

      【讨论】:

      • 我关心潜在的时间漂移​​。如何避免时间漂移?
      • apply_interval 应该相当不错,但文档仅声明“超时不准确,但至少与要求的时间一样长”。
      猜你喜欢
      • 2016-03-17
      • 2016-05-23
      • 1970-01-01
      • 2015-12-25
      • 1970-01-01
      • 1970-01-01
      • 2012-09-20
      • 2018-10-20
      • 1970-01-01
      相关资源
      最近更新 更多