[erlang-questions] gen_statem confusion

Raimo Niskanen raimo+erlang-questions@REDACTED
Fri Jan 20 09:00:59 CET 2017


On Thu, Jan 19, 2017 at 04:35:19PM +0000, Vans S wrote:
> Okay same problem with R19.2.1
> 
> 
> 
> On Thursday, January 19, 2017 11:15 AM, Vans S <vans_163@REDACTED> wrote:
> Yea ignore that. That is because I was not up to R19.2 when I tested. 
> Let me get up to date.
> 
> 
> 
> 
> On Thursday, January 19, 2017 11:08 AM, Vans S <vans_163@REDACTED> wrote:
> Actually I jumped the gun here:
> 
> 
> using a state_timeout as next event which is a valid 
> event_type() as said in the docs produces:
> 
> ** Reason for termination = error:{bad_action_from_state_function,
> {next_event,state_timeout,hi}}
> So state_timeout cant be used here. 
> 
> timeout,  cast, info can be used.
> 
> {call, pid()} also cant be used. 
> 

That is a bug!

I missed to add a clause in event_type/1 for state_timeout when I
introduced it.  The missing clause for {call,From} has always not
been there - amazing nobody noticed!

I guess generating events of type 'internal' is the really useful
feature - the other types are mostly of theoretical value.
Using them will most probably be confusing.

I will try to squeeze in to fix that for 19.3.

> 
> 
> 
> On Thursday, January 19, 2017 11:01 AM, Vans S <vans_163@REDACTED> wrote:
> > So if you in a state callback insert more next_event messages these are
> > inserted first in the queue, and a state_timeout 0 message is inserted last
> > in the queue.
> 
> This clarifies things nicely.  Also what if one was to use {next_event, state_timeout .. vs {state_timeout ..
> Also is there a priority such as external, internal, timeout, state_timeout, etc?

There is no priority between types.  First to enqueue is first to dequeue,
except for {next_event,_,_} actions that will be _before_ first to dequeue.

> 
> Or anything with next_event goes first into the queue (or top of stack if using {next_event, external .. ?) 
> regardless queue or stack the idea is the same, it will be first to dequeue/pop. And this will happen before receive 
> is called.

Precisely.  All {next_event,_,_} actions in an event handler return will
be the first to dequeue for the next event handler, and the order between
them is that the first in the event handler action list will be the first
to dequeue. 

So when the bug above has been fixed an action {next_event,state_timeout,_}
will produce an event that would be dequeued before the event from an action
{state_timeout,0,_}, with possible already enqueued events in between.

Furthermore multiple {next_event,state_timeout,_} actions will produce
one event each, but multiple {state_timeout,0,_} actions will override
each other so the last one wins hence only produce one event.

> 
> 
> 
> 
> 
> On Thursday, January 19, 2017 5:14 AM, Raimo Niskanen <raimo+erlang-questions@REDACTED> wrote:
> On Thu, Jan 19, 2017 at 11:59:37AM +0300, Alex S. wrote:
> 
> > 
> > > 19 янв. 2017 г., в 6:01, Vans S <vans_163@REDACTED> написал(а):
> > > 
> > > 
> > > 
> > > This wording is really confusing:
> > > 
> > >> instead the the time-out event is enqueued to ensure 
> > >> that it gets processed before any not yet received 
> > >> external event
> > > Because when I tried a test case
> > > 
> > > init() ->
> > >  send(self(), hi),
> > >  {_,_,_,0}.  %0 timeout basically
> > > 
> > > The 0 timeout procced before the 'hi' message.
> > > Using 1 as the timeout, 'hi' message procs first.
> > > 
> > > But it says not yet received external event.  To me send() seems like 
> > > an external event. Hence confusing.
> > Well, it was sent, but not yet received by the gen_statem’s main loop.
> 
> Perfectly correct.
> 
> While gen_statem processes enqueued events it is guaranteed to not enter a
> receive statement, so no new messages are received until after ther
> state_timeout 0 message.
> 
> Other enqueued messages that are being processed such as next_event
> messages will be processed before a state_timeout 0 message.
> 
> So if you in a state callback insert more next_event messages these are
> inserted first in the queue, and a state_timeout 0 message is inserted last
> in the queue.

-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB



More information about the erlang-questions mailing list