[erlang-questions] gen_statem state enter call and changing t oanother state
Fred Hebert
mononcqc@REDACTED
Mon Jun 11 18:55:40 CEST 2018
On 06/11, Raimo Niskanen wrote:
>The feature you ask for probably makes more sense for
>handle_event_function.
>
>But there are still some hairy semantics to get right:
>* If changing states in state_enter call hops more than once - what should
> OldState be after the first state_enter call? I.e how much of a state
> change should changing states in the state_enter call be regarded as.
> As the gen_statem code looks now it seems to be easier to retain
> the original OldState and not regard the state change as complete until
> the final state of the state change has been deduced.
>* If changing states back to the OldState - should postponed events be
> retried? I think not - you in effect stayed in the same state.
>* Same again: if changing states back to the OldState - should the state
> enter call of the OldState be re-run or not? As the gen_statem code
> looks now it seems to be hard to see this as anything else than staying
> in the same state hence not running the state_enter call.
> Is that intuitive?
>* Should we also allow {next_event,...} from a state_enter call?
>* There might be more...
- Would the state enter represent having entered the state or entering
the state as soon as the callback returns?
If it represents having entered the state:
- postponing would conceptually make sense, even if it won't in
practice (because you may just forever get back to the postponing
state)
- trace/debug calls need to show the state transition as having
happened with no actual events being generated (or rather event a
caused state to change to A, and then state changes B and C
happened with no prompting) -- otherwise you need to consider
state enter events the same way they'd be with external events and
that's even conceptually worse
- state timeouts are not ambiguous
- if the events entered the state, it does solve the 'OldState'
problem
If it does not represent having entered the state
- postponing would not conceptually make sense, and won't happen
- no hard questions about whether enter state events are special
events or not
- state timeouts should possibly not be reset since you have never
left the original state until at the end of evaluating the 'enter'
chain of events
- this ends up having the possibility to have a repeated 'OldState'
value, which currently clashes with the expectation that the first
enter event of a FSM is a duplicated one. This would make any
double-transition look like the first transition of the process's
loop.
It seems that either way, there is a conceptual confusion as soon as an
enter state event is allowed to force a change to a new state. I'd
rather see the possibility forbidden.
As for allowing next_event in an enter event, I'm not a fan. If you
really need an event to run as the first thing in an enter event, just
run it in the enter event itself? Otherwise this lets you conceptually
do the same thing as multiple enter-state events with a state transition
it seems.
>
>I think the semantics is hairy enough already, so I still have a bad
>feeling about this... But I have asked some colleauages to also
>contemplate it, we'll see if they can find the time since we are in
>the middle of the 21.0 release circus.
>
Yes. One of the main complaints of gen_statem is that it is a complex
behaviour and people take a long while to get adapted. It could be
argued that the separation between enter and normal events is already
part of that complexity, but in my opinion, not putting these barriers
in place actually increase the overall potential system complexity even
more.
I still think gen_statem should have been simpler than it is today, so
I'll be vocal about preventing further complexity from being added to
it.
>The only thing that _has_ to be prohibited from a state_enter call is
>'postpone' since there is no event to postpone.
>
>The only reason I have for prohibiting state change and event insertion
>from state_enter calls is that I am afraid they would get too hairy semantics
>and hence cause too hard to understand state machines.
>
Yes, that is an entirely valid concern. I think it is worth making the
existing typespecs a tad more complex to prevent user code from being
even worse than that.
Currently the typespecs are too obtuse to be good docs on their own
(while they're kind of okay for supervisors and gen_servers), but they
represent an intrinsinct complexity warning that a tutorial would have
to alert the user to anyway if they were to be simplified. Might as well
keep the type complexity and just have the tutorial fix things right
away.
I'm opposed to adding more conceptual complexity to gen_statem.
Regards,
Fred.
More information about the erlang-questions
mailing list