[erlang-questions] gen_statem state enter call and changing t oanother state

Frans Schneider fchschneider@REDACTED
Wed Jun 13 10:25:06 CEST 2018


Well, that was an enlightening discussion. Just ditched the initial 
implementation and started all over again. Conditions now are true 
conditions and events are real events. The number of states now is half 
the number they were, but the handle_event functions tend to be more 
complex. I could remove the whole state enter functionality.

Thanks,

Frans

On 06/13/2018 03:03 AM, Fred Hebert wrote:
> 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