【发布时间】:2012-03-22 21:03:17
【问题描述】:
我对 gen_fsm 超时有疑问。假设您有一组具有两种状态的 gen_fsm(将来可以更多):idle 是起始状态,working。
gen_fsm 将在任何 5 秒内检查特定参数,并据此将保留在 idle 或移动到 working。每当一个 gen_fsm 移动到 working 时,它都会向所有其他 gen_fsm 发送一条消息(使用 gen_fsm:send_all_state_event/2):idle 中的那些应该移动到 working 而working 中的那个不应该关心传入的消息。
现在,关键是我不想在状态超时中出现偏差(例如,如果机器在 working 中持续 3 秒并收到一条消息会发生什么?5 秒超时不再有效,因为无论如何我都想保留一个固定的超时时间(这意味着应该在固定的时间触发超时消息)。
这是我的解决方案的主要部分,它使用了now() 和time:now_diff/2。无论如何,我有一点偏差,但自从谈到几分之一秒后似乎很公平。
你认为它有效吗?
{ok, idle, #state{time = now()}, 5000}.
idle(timeout, State) ->
%% do some operations
{next_state, idle, State#state{time = now()}, 5000}.
working(timeout, State) ->
%% do some other actions
{next_state, working, State#state{time = now()}, 5000}.
handle_event(work, working, #state{time = Time} = State) ->
Timeout = round(timer:now_diff(now(), Time) / 1000),
{next_state, working, State, Timeout}.
handle_event(work, StateName, state{time = Time} = State) ->
Timeout = round(timer:now_diff(now(), Time) / 1000),
{next_state, working, State, Timeout}.
【问题讨论】: