From 04d40c5cd18aca449606c19608e8044f593ee99e Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 22 Sep 2016 17:40:47 +0200 Subject: Change state entry events into state enter calls --- lib/stdlib/doc/src/gen_statem.xml | 305 ++++++++++++++++++++++++++++---------- 1 file changed, 226 insertions(+), 79 deletions(-) (limited to 'lib/stdlib/doc/src') diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index 944e9ab13b..aa34f53d29 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -54,7 +54,8 @@

This is a new behavior in Erlang/OTP 19.0. It has been thoroughly reviewed, is stable enough - to be used by at least two heavy OTP applications, and is here to stay. + to be used by at least two heavy OTP applications, + and is here to stay. Depending on user feedback, we do not expect but can find it necessary to make minor not backward compatible changes into Erlang/OTP 20.0. @@ -70,7 +71,7 @@ The state can be any term. Events can be postponed. Events can be self-generated. - Automatic state entry events can be generated. + Automatic state enter code can be called. A reply can be sent from a later state. There can be multiple sys traceable replies. @@ -195,10 +196,14 @@ erlang:'!' -----> Module:StateName/3 to force processing an inserted event before others.

- The gen_statem engine can automatically insert - a special event whenever a new state is entered; see - state_entry_mode(). - This makes it easy to handle code common to all state entries. + The gen_statem engine can automatically + make a specialized call to the + state function + whenever a new state is entered; see + state_enter(). + This is for writing code common to all state entries. + Another way to do it is to insert events at state transitions, + but you have to do so everywhere it is needed.

If you in gen_statem, for example, postpone @@ -526,6 +531,20 @@ handle_event(_, _, State, Data) ->

+ + + +

+ This is the return type from + Module:callback_mode/0 + and selects + callback mode + and whether to do + state enter calls, + or not. +

+
+
@@ -558,44 +577,48 @@ handle_event(_, _, State, Data) -> - +

- The state entry mode is selected when starting the - gen_statem and after code change - using the return value from + If the state machine should use state enter calls + is selected when starting the gen_statem + and after code change using the return value from Module:callback_mode/0.

If Module:callback_mode/0 - returns a list containing state_entry_events, + returns a list containing state_enter, the gen_statem engine will, at every state change, - insert an event of type - enter - with content OldState. This event will be inserted - before all other events such as those generated by - action() - next_event. + call the + state function + with arguments (enter, OldState, Data). + This may look like an event but is really a call + performed after the previous state function returned + and before any event is delivered to the new state function. + See + Module:StateName/3 + and + Module:handle_event/4.

If Module:callback_mode/0 - does not return such a list, no state entry events are inserted. + does not return such a list, no state enter calls are done.

- No state entry event will be inserted after a + If Module:code_change/4 - since transforming the state to a newer version is regarded - as staying in the same state even if the newer version state - should have a different name. + should transform the state to a state with a different + name it is still regarded as the same state so this + does not cause a state enter call.

- Note that a state entry event will be inserted - when entering the initial state even though this formally - is not a state change. In this case OldState - will be the same as State, which can not happen - for an actual state change. + Note that a state enter call will be done + right before entering the initial state even though this + formally is not a state change. + In this case OldState will be the same as State, + which can not happen for a subsequent state change.

@@ -605,8 +628,7 @@ handle_event(_, _, State, Data) ->

Transition options can be set by actions - and they modify the following in how - the state transition is done: + and they modify how the state transition is done:

@@ -636,17 +658,22 @@ handle_event(_, _, State, Data) -> action() next_event are inserted in the queue to be processed before - all other events. + other events.

- If the state changes or is the initial state, and the - state entry mode - is state_entry_events, an event of type - enter - with content OldState is inserted - to be processed before all other events including those above. + If the state changes or is the initial state, and + state enter calls + are used, the gen_statem calls + the new state function with arguments + (enter, OldState, Data). + If this call returns any + actions + that sets transition options + they are merged with the current + That is: hibernate and timeout overrides + the current and reply sends a reply.

@@ -656,8 +683,9 @@ handle_event(_, _, State, Data) -> is set through action() timeout, - an event timer can be started or a time-out zero event - can be enqueued. + an event timer is started if the value is less than + infinity or a time-out zero event + is enqueued if the value is zero.

@@ -732,7 +760,7 @@ handle_event(_, _, State, Data) -> is processed before any not yet received external event.

- Notice that it is not possible or needed to cancel this time-out, + Note that it is not possible or needed to cancel this time-out, as it is cancelled automatically by any other event.

@@ -743,7 +771,10 @@ handle_event(_, _, State, Data) ->

These state transition actions can be invoked by returning them from the - state function, from + state function + when it is called with an + event, + from Module:init/1 or by giving them to enter_loop/5,6. @@ -757,8 +788,8 @@ handle_event(_, _, State, Data) -> override any previous of the same type, so the last in the containing list wins. For example, the last - event_timeout() - overrides any other event_timeout() in the list. + postpone() + overrides any previous postpone() in the list.

postpone @@ -775,6 +806,53 @@ handle_event(_, _, State, Data) -> as there is no event to postpone in those cases.

+ next_event + +

+ Stores the specified EventType + and EventContent for insertion after all + actions have been executed. +

+

+ The stored events are inserted in the queue as the next to process + before any already queued events. The order of these stored events + is preserved, so the first next_event in the containing + list becomes the first to process. +

+

+ An event of type + internal + is to be used when you want to reliably distinguish + an event inserted this way from any external event. +

+
+ + + + + + +

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

+

+ Actions are executed in the containing list order. +

+

+ Actions that set + transition options + override any previous of the same type, + so the last in the containing list wins. + For example, the last + event_timeout() + overrides any previous event_timeout() in the list. +

+ hibernate

@@ -805,32 +883,6 @@ handle_event(_, _, State, Data) -> to Time with EventContent.

- reply_action() - -

- Replies to a caller. -

-
- next_event - -

- Stores the specified EventType - and EventContent for insertion after all - actions have been executed. -

-

- The stored events are inserted in the queue as the next to process - before any already queued events. The order of these stored events - is preserved, so the first next_event in the containing - list becomes the first to process. -

-

- An event of type - internal - is to be used when you want to reliably distinguish - an event inserted this way from any external event. -

-
@@ -838,13 +890,31 @@ handle_event(_, _, State, Data) ->

- Replies to a caller waiting for a reply in + This state transition action can be invoked by + returning it from the + state function, from + Module:init/1 + or by giving it to + enter_loop/5,6. +

+

+ It replies to a caller waiting for a reply in call/2. From must be the term from argument {call,From} - to the + in a call to a state function.

+

+ Note that using this action from + Module:init/1 + or + enter_loop/5,6 + would be weird on the border of whichcraft + since there has been no earlier call to a + state function + in this server. +

@@ -868,6 +938,27 @@ handle_event(_, _, State, Data) ->

+ + + + + next_state + +

+ The gen_statem does a state transition to + NextStateName + (which can be the same as the current state), + sets NewData, + and executes all Actions. +

+
+
+

+ All these terms are tuples or atoms and this property + will hold in any future version of gen_statem. +

+
+
@@ -889,6 +980,27 @@ handle_event(_, _, State, Data) ->

+ + + + + next_state + +

+ The gen_statem does a state transition to + NextState + (which can be the same as the current state), + sets NewData, + and executes all Actions. +

+
+
+

+ All these terms are tuples or atoms and this property + will hold in any future version of gen_statem. +

+
+
@@ -1148,10 +1260,11 @@ handle_event(_, _, State, Data) -> {call,From} to the state function. - From and Reply - can also be specified using a - reply_action() - and multiple replies with a list of them. + A reply or multiple replies canalso be sent + using one or several + reply_action()s + from a + state function.

@@ -1362,7 +1475,8 @@ handle_event(_, _, State, Data) -> once after server start and after code change, but before the first state function - is called. More occasions may be added in future versions + in the current code version is called. + More occasions may be added in future versions of gen_statem.

@@ -1380,7 +1494,7 @@ handle_event(_, _, State, Data) -> or a list containing callback_mode() and possibly the atom - state_entry_events. + state_enter.

@@ -1601,7 +1715,8 @@ handle_event(_, _, State, Data) ->

The function is to return Status, a term that - changes the details of the current state and status of + contains the appropriate details + of the current state and status of the gen_statem. There are no restrictions on the form Status can take, but for the sys:get_status/1,2 @@ -1625,11 +1740,17 @@ handle_event(_, _, State, Data) -> + Module:StateName(enter, OldState, Data) -> + StateFunctionEnterResult + Module:StateName(EventType, EventContent, Data) -> StateFunctionResult - Module:handle_event(EventType, EventContent, - State, Data) -> HandleEventResult + Module:handle_event(enter, OldState, State, Data) -> + HandleEventResult + + Module:handle_event(EventType, EventContent, State, Data) -> + HandleEventResult Handle an event. @@ -1650,10 +1771,18 @@ handle_event(_, _, State, Data) -> StateFunctionResult = state_function_result() + + StateFunctionEnterResult = + state_function_enter_result() + HandleEventResult = handle_event_result() + + HandleEventEnterResult = + handle_event_enter_result() +

@@ -1694,6 +1823,24 @@ handle_event(_, _, State, Data) -> by gen_statem after returning from this function, see action().

+

+ When the gen_statem runs with + state enter calls, + these functions are also called with arguments + (enter, OldState, ...) whenever the state changes. + In this case there are some restrictions on the + actions + that may be returned: + postpone() + and + {next_event,_,_} + are not allowed. + You may also not change states from this call. + Should you return {next_state,NextState, ...} + with NextState =/= State the gen_statem crashes. + You are advised to use {keep_state,...} or + keep_state_and_data. +

Note the fact that you can use throw -- cgit v1.2.3