I have a question on gen_fsm timeout. Let's say you have a set of gen_fsm with two states (in future can be more): idle which is the starting state and working.
Any 5 seconds the gen_fsm will check a particular parameter and according to it will remain in idle or will move to working. Whenever a gen_fsm will move to working, it will send a message (using gen_fsm:send_all_state_event/2) to all the other gen_fsm: the ones in idle should move to working while the one in working should not care about the incoming message.
Now, the point is that I don't want to have a skew in the states timeout (e.g. what happens if the machine is in working for 3 seconds and receives a message? A 5 seconds timeout is no more valid, since I want to preserve a fixed timeout no matter what (this means that a timeout message should be triggered at fixed times).
Here are the salient parts of my solution, which uses now() and time:now_diff/2. I have a small drift anyhow, but seems fair since talking about fractions of seconds.
Do you think it is valid?
{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}.