关于Erlang send_after延迟消息与gen_fsm处理的技术问询
Erlang实现最长48小时的延迟消息调度(搭配gen_fsm使用)
我最近做了个Erlang的延迟消息调度实现,最长能支持48小时的延迟,搭配gen_fsm使用挺顺手的,给大家拆解下:
核心延迟消息发送函数
这部分负责计算延迟时间并调度消息发送:
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.
逻辑说明
- 先通过
os:system_time(micro_seconds)获取当前系统的微秒级时间,再转换为毫秒单位,和传入的目标时间戳TsMsec计算差值,得到实际需要延迟的毫秒数 - 如果计算出的延迟时间是非负的(也就是目标时间还没到),就调用
erlang:send_after给当前进程发送指定消息;要是目标时间已经过去了,就直接忽略这个调度请求,避免发送过期消息
在gen_fsm中处理延迟消息
当延迟时间到期后,消息会以handle_info的形式被gen_fsm进程接收,处理代码示例如下:
handle_info({new_status,{Status,HrQtKey}},StateName,State) -> % 这里添加你的业务逻辑处理代码,比如更新状态、触发后续业务动作等 {next_state,StateName,State};
处理说明
- 收到
{new_status,{Status,HrQtKey}}这类延迟消息时,在handle_info回调里编写对应的业务逻辑,处理完成后返回{next_state,StateName,State}就能保持当前状态机的状态不变;如果业务需要切换状态,也可以在这里返回对应的状态切换指令
这个实现专门用来处理最长48小时的延迟消息调度,多数情况下延迟时长在数小时范围内,依托Erlang原生的send_after机制,能保证消息调度的可靠性,很适合需要定时触发状态更新或特定业务动作的场景。
内容的提问来源于stack exchange,提问作者Anton Prokofiev
相关产品推荐
相关产品推荐

