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