elixir创建一个在每个给定时间内打勾的前台进程的最佳方法是什么?
我的主要问题是这样的方法:
defmoulde Ticker do
def tick do
do_something()
:timer.sleep(1000)
tick
end
end
有效,但设计错误。它肯定不会每秒都在滴答作响,但是每秒都会增加do_something()的时间。 我可以产生一个处理“某事”的过程,但仍有一个小的滞后。
另外,我正在尝试构建一个混合应用程序,有一些GenServers参与,以及一个主要的前台进程(我在这里问的那个)应该每隔x秒调用一次服务器。有这样的otp方法吗?
答案 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