gen_fsm erlang timeout - PullRequest
       23

gen_fsm erlang timeout

1 голос
/ 05 марта 2012

У меня вопрос по тайм-ауту gen_fsm. Допустим, у вас есть набор gen_fsm с двумя состояниями (в будущем может быть больше): idle, которое является начальным состоянием, и working.

Каждые 5 секунд gen_fsm проверит определенный параметр и в соответствии с ним останется в idle или перейдет к working. Всякий раз, когда gen_fsm переместится на working, он отправит сообщение (используя gen_fsm:send_all_state_event/2) всем другим gen_fsm: те, что в 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}.

1 Ответ

4 голосов
/ 05 марта 2012

Вы можете использовать либо timer: apply_interval для вызова функции API, которая отправляет событие в ваш fsm.

Или вы используете timer: send_interval для отправкипользовательское сообщение, которое вы можете обработать в обратном вызове handle_info в вашем gen_fsm.

...