erlang - 在 Erlang 中定期做某事的最佳方法是什么?

标签 erlang erlang-otp

我有一个需要每十五秒做一些工作的过程。我目前正在这样做:

-behavior(gen_server).

interval_milliseconds ()-> 15000.
init()->
    {ok, 
     _State = FascinatingStateData,
     _TimeoutInterval = interval_milliseconds ()
    }.

%% This gets called automatically as a result of our handlers
%% including the optional _TimeoutInterval value in the returned
%% Result
handle_info(timeout, StateData)->
    {noreply, 
     _State = do_some_work(StateData),
      _TimeoutInterval = interval_milliseconds ()
    }.

这可行,但非常脆弱:如果我想教我的服务器一条新消息,当我编写任何新的处理函数时,我必须记住在其返回值中包含可选的超时间隔。也就是说,如果我正在处理同步调用,我需要这样做:

%% Someone wants to know our state; tell them
handle_call(query_state_data, _From, StateData)->
    {reply, StateData, _NewStateData = whatever (), interval_milliseconds ()};

代替

%% Someone wants to know our state; tell them
handle_call(query_state_data, _From, StateData)->
    {reply, StateData, _NewStateData = whatever ()};

正如您可能猜到的那样,我已经多次犯过这个错误。这很糟糕,因为一旦代码处理了该 query_state_data 消息,就不再生成超时,整个服务器就会停止运行。 (我可以通过在机器上获取外壳并手动发送“超时”消息来手动“除颤”,但是...... eww。)

现在,我可以尝试记住始终在我的 Result 值中指定可选的 Timeout 参数。但这不成比例:总有一天我会忘记,并且会再次盯着这个错误。那么:什么是更好的方法?

我不认为我想编写一个永远运行并且大部分时间都在 sleep 的实际循环;这似乎与 OTP 的精神背道而驰。

最佳答案

使用timer :发送间隔/2。例如。:

-behavior(gen_server).

interval_milliseconds()-> 15000.
init()->
    timer:send_interval(interval_milliseconds(), interval),
    {ok, FascinatingStateData}.

%% this clause will be called every 15 seconds
handle_info(interval, StateData)->
    State2 = do_some_work(StateData)
    {noreply, State2}.

关于erlang - 在 Erlang 中定期做某事的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/769466/

相关文章:

javascript - 一个叫做 struggle 的高阶函数怎么样?

performance - Erlang VM 是否为 CPU 的每个硬件核心创建单线程?

networking - Erlang:以编程方式启动远程节点

erlang - 将列表列表转换为元组列表的最佳方法?

automated-tests - 如何在 eunit 中使用 debugMsg 以及如何在 eunit 测试中打印一些内容,尽管测试超时

mysql - 如何在 Erlang 中安装驱动程序? (特别是 MySQL-otp 驱动程序)

erlang - 如何使用应用程序:get_env() in Erlang/OTP?

erlang - 如何通过动态监督确定RestartStrategy

elixir - Elixir OTP Supervisor 检测到崩溃的进程时记录错误

timer - Erlang 定时器可以扩展吗?