[erlang-questions] gen_statem state enter call and changing t oanother state
Fred Hebert
mononcqc@REDACTED
Wed Jun 13 03:03:43 CEST 2018
On 06/12, Frans Schneider wrote:
>
>__|_____________|_____________________________|____________________
>T2|waiting |HEARTBEAT message is received|if (HB.FinalFlag ==
> | | | NOT_SET) then
> | | | must_send_ack else if
> | | | (HB.LivelinessFlag ==
> | | | NOT_SET) then
> | | | may_send_ack
> | | |else
> | | | waiting
>__|_____________|_____________________________|____________________
>T3|may_send_ack |GuardCondition: |waiting
> | | WP::missing_changes() == |
> | | <empty> |
>__|_____________|_____________________________|____________________
>T4|may_send_ack |GuardCondition: |must_send_ack
> | | WP::missing_changes() != |
> | | <empty> |
>__|_____________|_____________________________|____________________
>T5|must_send_ack|after(R::heartbeatResponseDelay) waiting
>__|_____________|_____________________________|____________________
>
>Transitions T3/T4 are just begging for a enter state with next_state.
>The alternative would be to put the guard conditions at the end of T2,
>which of course is not that bad but it messes up the line of thinking
>of the original protocol designers and its readers. Also, T3/T4 could
>just become something like:
>
>handle_event(enter,
> _Old_state,
> #state{state2 = may_send_ack} = State,
> #data{missing_changes = []} = Data) ->
> {next_state, waiting, Data};
>handle_event(enter,
> _Old_state,
> #state{state2 = may_send_ack} = State,
> Data) ->
> ...
> {next_state, must_send_ack, Data};
>
>which I think is very accurate. In the example, there is only T2 as
>the old state but there are other examples with more than one
>originating states.
>
Have you considered:
handle_event(..., ..., t2, Data) ->
...
{next_state, may_send_ack, NewData,
[{next_event, internal, switch_states}]};
handle_event(internal, switch_states, maybe_send_ack, Data) ->
case Data of
#data{missing_changes=[]} ->
{next_state, waiting, Data};
_ ->
{next_state, must_send_ack, Data}
end;
...
Using next_event to force-enqueue the next event lets you do a switch
through a state transition based entirely on its internal state. It does
require any transition to 'may_send_ack' to set that value, though.
More information about the erlang-questions
mailing list