[erlang-questions] gen_statem state enter call and changing t oanother state
Frans Schneider
fchschneider@REDACTED
Tue Jun 12 16:37:51 CEST 2018
Indeed, the specs are a little weird. It's for a reason the organization
calls itself OMG.
Frans
On 06/12/2018 03:47 PM, Raimo Niskanen wrote:
> On Tue, Jun 12, 2018 at 02:14:45PM +0200, Frans Schneider wrote:
>>
>>
>> On 06/12/2018 12:31 PM, Ingela Andin wrote:
>>> Hi!
>>>
>>> Could it be so that you are trying to solve the problem in the wrong
>>> place? State enter actions are good for example starting a timer, but I
>>> think it is illogical to change the state.
>>> It sound to me like you could do so pattern matching, maybe in
>>> conjunction with some guards in the your state function clauses and if
>>> your conditions are meet maybe
>>> all that clause does is to change state.
>>>
>>> Regards Ingela Erlang/OTP team - Ericsson AB
>>>
>>>
>>
>> Of course I can, but in this particular case it would lead to simpler
>> code. For example, I have the following state changes defined ([1] par.
>> 8.4.12.2):
>>
>> __|_____________|_____________________________|____________________
>> 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.
>>
>> Frans
>>
>> [1] https://www.omg.org/spec/DDSI-RTPS/2.2/PDF
>
> Your example illustrates the problem.
>
> But I think the specification in question is very strange, and an ill fit
> for an event driven state machine.
>
> I can see that "HEARTBEAT message is received" is an event, but think it is
> very strange that [WP::missing_changes() == <empty>] is an event - it seems
> more like a condition on the state, and hence the state may_send_ack appears
> to not be a state but instead some kind of decision point.
>
> So the state chart "8.24 - Behavior of the Reliable StatefulReader with
> respect to each matched Writer" seems to be a mix of a state diagram and a
> flowchart.
>
> Also, specifying a state machine as a table of transitions is a bit odd, but
> gets even more peculiar when the events are e.g "RTPS Reader is configured with
> a matched RTPS Writer." or "GuardCondition: WP::missing_changes() == <empty>"
> - here again a mix between a state transition table and flowchart conditions.
>
> Since the specification in question seems to be quite far from an event driven
> state machine it is no wonder if it seems to fit gen_statem poorly... :-(
>
> Implementing flowchart logic via pseudo state changes calling back and
> forth between the behaviour engine and the callback module is strange and
> inefficient, but in this case has the advantage of making the
> implementation kind of match the specification.
>
> So the question boils down to; would allowing state change from state enter
> calls be bad for what gen_statem is intended to be good at?
>
> / Raimo
>
>
>
>>
>>>
>>> 2018-06-12 10:31 GMT+02:00 Frans Schneider <fchschneider@REDACTED
>>> <mailto:fchschneider@REDACTED>>:
>>>
>>>
>>>
>>> On 06/12/2018 10:06 AM, Raimo Niskanen wrote:
>>>
>>>
>>> I agree. State enter calls were introduced to allow code to be
>>> run when a
>>> state is entered, without having to duplicate that code at every
>>> state exit
>>> from the previous state. It is a feature existing in other
>>> state machine
>>> description languages e.g OpenBSD's ifstated.
>>>
>>> This is the exact reason for bringing up the whole issue. And
>>> sometimes, that requires a next_state NewState.
>>>
>>>
>>>
>>> Frans
>>>
>
More information about the erlang-questions
mailing list