如何使用elixir创建一个事件发射器,otp方式

时间:2015-07-14 14:57:47

标签: elixir otp eventemitter

elixir创建一个在每个给定时间内打勾的前台进程的最佳方法是什么?

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

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

有效,但设计错误。它肯定不会每秒都在滴答作响,但是每秒都会增加do_something()的时间。 我可以产生一个处理“某事”的过程,但仍有一个小的滞后。

另外,我正在尝试构建一个混合应用程序,有一些GenServers参与,以及一个主要的前台进程(我在这里问的那个)应该每隔x秒调用一次服务器。有这样的otp方法吗?

2 个答案:

答案 0 :(得分:14)

我认为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包裹并插入监督树(如果你不关心潜在的轻微漂移)。

答案 1 :(得分:2)

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

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

: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