From 8b16506b0763d13b69aef3baeabef4729c708fe5 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 24 Feb 2016 15:50:29 +0100 Subject: Make first next_event in list arrive first Define options as actions that set options, rework the documentation about this. --- lib/stdlib/doc/src/gen_statem.xml | 298 +++++++++++++++++++++++--------------- 1 file changed, 185 insertions(+), 113 deletions(-) (limited to 'lib/stdlib/doc') diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index 8934d912c6..1e41d616e9 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -143,8 +143,8 @@ erlang:'!' -----> Module:StateName/4

The state function can insert events using the - - transition_action() next_event + + action() next_event and such an event is inserted as the next to present to the state function. That is: as if it is @@ -158,12 +158,19 @@ erlang:'!' -----> Module:StateName/4

Inserting an event replaces the trick of calling your own state handling functions that you often would have to resort to in e.g gen_fsm - to force processing a faked event before others. + to force processing an inserted event before others. If you for example in gen_statem postpone an event in one state and then call some other state function of yours, you have not changed states and hence the postponed event will not be retried, which is logical but might be confusing.

+

+ See the type + + transition_option(). + + for the details of a state transition. +

A gen_statem handles system messages as documented in sys. The sys module @@ -184,7 +191,7 @@ erlang:'!' -----> Module:StateName/4 state function or Module:init/1 specifies 'hibernate' in the returned - Ops + Actions list. This might be useful if the server is expected to be idle for a long time. However use this feature with care since hibernation implies at least two garbage collections @@ -281,8 +288,8 @@ erlang:'!' -----> Module:StateName/4

Destination to use when replying through for example the - - transition_op() {reply,Caller,Reply} + + action() {reply,Caller,Reply} to a process that has called the gen_statem server using call/2. @@ -344,10 +351,11 @@ erlang:'!' -----> Module:StateName/4

A fun() of arity 2 that takes an event and returns a boolean. - When used in {remove_event,RemoveEventPredicate} from - transition_op(). - The event for which the predicate returns true will - be removed. + When used in the + action() + {remove_event,RemoveEventPredicate}, + the event for which the predicate returns true + will be removed.

The predicate may not use a throw exception @@ -384,40 +392,45 @@ erlang:'!' -----> Module:StateName/4 - + -

Either a - - transition_option() - of which the last occurence - in the containing list takes precedence, or a - - transition_action() - performed in the order of the containing list. -

-

These may be returned from the - state function, - from Module:init/1 - or given to - enter_loop/6,7. +

+ Transition options may be set by + actions + and they modify how the state transition is done:

-

The processing order for a state change is:

- If the option postpone is true - the current event is postponed. + All + actions + are processed in order of appearance. - If the state changes the queue of incoming events - is reset to start with the oldest postponed. + + If the + + transition_option() + + postpone + is true the current event is postponed. - All actions are processed in order of appearance. + + If the state changes the queue of incoming events + is reset to start with the oldest postponed. - The timeout option is processed if present, - so a state timer may be started or a timeout zero event + + If the + + transition_option() + + + timeout + + is set a state timer may be started or a timeout zero event may be enqueued as the newest incoming. - The (possibly new) - state function - is called with the oldest enqueued event if there is any, + + The (possibly new) + state function + is called with the oldest enqueued event if there is any, otherwise the gen_statem goes into receive or hibernation (if the option hibernate is true) to wait for the next message. In hibernation the next @@ -429,91 +442,145 @@ erlang:'!' -----> Module:StateName/4 - + + +

+ If true postpone the current event and retry + it when the state changes that is: + NewState =/= State. +

+
+
+ + + +

+ If true hibernate the gen_statem + by calling + + proc_lib:hibernate/3 + + before going into receive + to wait for a new external event. + If there are enqueued events the hibernate + is ignored as if an event just arrived and awakened + the gen_statem. +

+
+
+ + -

If multiple state options of the same kind are present - in the containing list these are set in the list order - and the last value is kept. +

+ Generate an event of + type timeout + after this time (in milliseconds) unless some other + event arrives in which case this timeout is cancelled. + Note that a retried or inserted event + counts just like a new in this respect. + If the value is infinity no timer is started. + If it is 0 the timeout event + is immediately enqueued as the newest received. + Also note that it is not possible nor needed + to cancel this timeout using the + + action() cancel_timer. + + since this timeout is cancelled automatically by any other event. +

+
+
+ + + +

These state transition actions may be invoked by + returning them from the + state function, + from Module:init/1 + or by giving them to + enter_loop/6,7. +

+

Actions are executed in the containing list order. + The order matters for some actions such as next_event + and reply_action(). The order can in peculiar cases + matter for remove_event with + EventPredicate versus other + event removal actions. +

+

+ The order also matters for actions that set + + transition options + + since setting an option overrides any previous + of the same kind, so the last in the containing list wins.

postpone - If Postpone =:= true - or plain postpone postpone the current event - to be retried after a state change. - This option is ignored when returned from + + Set the + + transition_option() postpone + + for this state transition. + This action is ignored when returned from Module:init/1 or given to enter_loop/5,6 since there is no event to postpone in those cases. hibernate - If Hibernate =:= true - or plain hibernate hibernate the gen_statem - by calling - - proc_lib:hibernate/3 - before receive to wait for a new event. - If there are enqueued events the hibernate action - is ignored as if an event just arrived and awakened - the gen_statem. + + Set the + + transition_option() hibernate + + for this state transition. - timeout - - Generate an event of - type timeout - after Time milliseconds unless some other - event is received before that time. Note that a retried - or inserted event counts just like a new in this respect. - If Time =:= infinity no timer is started. - If Time =:= 0 the timeout event - is immediately enqueued as the newest received. - Also note that it is not possible nor needed - to cancel this timeout using the - - transition_action() - cancel_timer. - This timeout is cancelled automatically by any other event. + timeout + + Set the + + transition_option() timeout + + to Time with the + EventContent as Msg + for the next state. - -
-
- - - -

The state transition actions are executed - in the containing list order. This matters - for next_event where the last such in the list - will become the next event to process by - the current state function. Regarding the other actions - it is only for remove_event with - EventPredicate - and for reply_action() that the order may matter. -

- reply_action() Reply to a caller. next_event - Insert the given EventType + + Insert the given EventType and EventContent as the next to process. This will bypass any events in the process mailbox as well as any other queued events. An event of type internal - should be used when you want to reliably distinguish + + should be used when you want to reliably distinguish an event inserted this way from any external event. + If there are multiple next_event actions + in the containing list they are buffered and all are + inserted so the first in the list will be the + first to process. remove_event - Remove the oldest queued event + + Remove the oldest queued event that matches equal to EventType and EventContent or for which - EventPredicate returns true. + EventPredicate + returns true. cancel_timer - Cancel the timer by calling + + Cancel the timer by calling erlang:cancel_timer/2 - with TimerRef, + + with TimerRef, clean the process message queue from any late timeout message, and removes any late timeout message from the gen_statem event queue using @@ -523,16 +590,20 @@ erlang:'!' -----> Module:StateName/4 the primitives mentioned above. demonitor - Like cancel_timer above but for + + Like cancel_timer above but for demonitor/2 - with MonitorRef. + + with MonitorRef. unlink - Like {cancel_timer,_} above but for + + Like {cancel_timer,_} above but for unlink/1 - with Id. + + with Id.
@@ -574,19 +645,19 @@ erlang:'!' -----> Module:StateName/4 NewState (which may be the same as the current state), set NewData - and execute all Ops + and execute all Actions
keep_state The gen_statem will keep the current state, or do a state transition to the current state if you like, set NewData - and execute all Ops + and execute all Actions keep_state_and_data The gen_statem will keep the current state, or do a state transition to the current state if you like, keep the current server data, - and execute all Ops + and execute all Actions @@ -776,8 +847,8 @@ erlang:'!' -----> Module:StateName/4 state function returns with {reply,Caller,Reply} as one - - transition_op() + + action() , and that Reply becomes the return value of this function. @@ -870,20 +941,20 @@ erlang:'!' -----> Module:StateName/4 Enter the gen_statem receive loop -

If Server_or_Ops is a list() +

If Server_or_Actions is a list() the same as enter_loop/7 except that no server_name() must have been registered and - Ops = Server_or_Ops. + Actions = Server_or_Actions.

Otherwise the same as enter_loop/7 with - Server = Server_or_Ops and - Ops = []. + Server = Server_or_Actions and + Actions = [].

@@ -917,7 +988,7 @@ erlang:'!' -----> Module:StateName/4
name must have been registered accordingly before this function is called.

CallbackMode, State, - Data and Ops + Data and Actions have the same meanings as in the return value of Module:init/1. Also, the callback module Module @@ -952,7 +1023,7 @@ erlang:'!' -----> Module:StateName/4 Args = term() Result = {CallbackMode,State,Data} -  | {CallbackMode,State,Data,Ops} +  | {CallbackMode,State,Data,Actions}  | {stop,Reason} | ignore CallbackMode = callback_mode() @@ -960,8 +1031,9 @@ erlang:'!' -----> Module:StateName/4 State = state() Data = data() - Ops = - [transition_op()] + Actions = + [action()] | + action() Reason = term() @@ -978,7 +1050,7 @@ erlang:'!' -----> Module:StateName/4 function.

If the initialization is successful, the function should return {CallbackMode,State,Data} or - {CallbackMode,State,Data,Ops}. + {CallbackMode,State,Data,Actions}. CallbackMode selects the callback_mode(). of the gen_statem. @@ -986,7 +1058,7 @@ erlang:'!' -----> Module:StateName/4 of the gen_statem and Data the server data()

-

The Ops +

The Actions are executed when entering the first state just as for a state function. @@ -1047,7 +1119,7 @@ erlang:'!' -----> Module:StateName/4 from this or from any other state function by returning with {reply,Caller,Reply} in - Ops, in + Actions, in Replies or by calling @@ -1066,7 +1138,7 @@ erlang:'!' -----> Module:StateName/4 all postponed events will be retried in the new state.

See - transition_op() + action() for options that can be set and actions that can be done by gen_statem after returning from this function.

@@ -1102,7 +1174,7 @@ erlang:'!' -----> Module:StateName/4 is terminating. If it is because another callback function has returned a stop tuple {stop,Reason} in - Ops, + Actions, Reason will have the value specified in that tuple. If it is due to a failure, Reason is the error reason.

-- cgit v1.2.3