【问题标题】:erlang:send_after message delayerlang:send_after 消息延迟
【发布时间】:2018-10-11 01:42:44
【问题描述】:

我有以下代码:

send_event_at({TsMsec,Msg}) -> 
    Now = os:system_time(micro_seconds),
    NowMsec = erlang:convert_time_unit(Now,micro_seconds,milli_seconds),
    DelayMsec = TsMsec - NowMsec,
    if DelayMsec >= 0  ->
            erlang:send_after(DelayMsec,self(),Msg);
      true -> ignore
end.

然后在 gen_fsm 我将这些消息处理为:

handle_info({new_status,{Status,HrQtKey}},StateName,State) ->
     .....
    {next_state,StateName,State};

用于发送延迟最多 48 小时的消息的代码。 大多数时候一切都很好。

但如果我的 gen_fsm 有相当数量的传入消息,new_status 消息最多会延迟 15 分钟。

这个bug出现的频率不是太高,但确实很烦人。

想一想可能是什么原因,最好的解决方法是什么?

【问题讨论】:

    标签: erlang gen-fsm


    【解决方案1】:

    一些线索:

    • 你收到的时间是绝对时间,erlang中有很多时间源(见Time and Time Correction in Erlang),所以将os:system_time和Erlang Monotonic Time结合起来是有风险的,你应该注意TsMsec 参数的时间参考。
    • 在我看来,直接在参数中使用相对延迟应该更容易。
    • send_after 函数使用 Erlang 单调时间 - 从文档中不清楚它是使用绝对时间还是相对时间(尽管我认为它是绝对时间)。据说 Erlang Monitonic Time 精度取决于
      • OS 单调时间的准确度和精度
      • 操作系统系统时间的准确性和精度
      • 使用时间扭曲模式

    【讨论】:

    • 实际上 TsMsec 使用相同的函数:os:system_time(),我将它包装在我的 lib 中,并且从不使用“本机”erlang 函数,所以我知道有相同的时间源。我有这个 gen_fsm 的多个副本,大致同时开始,但我只有在后面的情况下才有时间偏差....
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 2011-05-25
    • 2019-07-26
    • 2019-08-01
    相关资源
    最近更新 更多