aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/doc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib/doc')
-rw-r--r--lib/stdlib/doc/src/gen_statem.xml305
1 files changed, 226 insertions, 79 deletions
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 @@
<p>
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 @@
<item>The state can be any term.</item>
<item>Events can be postponed.</item>
<item>Events can be self-generated.</item>
- <item>Automatic state entry events can be generated.</item>
+ <item>Automatic state enter code can be called.</item>
<item>A reply can be sent from a later state.</item>
<item>There can be multiple <c>sys</c> traceable replies.</item>
</list>
@@ -195,10 +196,14 @@ erlang:'!' -----> Module:StateName/3
to force processing an inserted event before others.
</p>
<p>
- The <c>gen_statem</c> engine can automatically insert
- a special event whenever a new state is entered; see
- <seealso marker="#type-state_entry_mode"><c>state_entry_mode()</c></seealso>.
- This makes it easy to handle code common to all state entries.
+ The <c>gen_statem</c> engine can automatically
+ make a specialized call to the
+ <seealso marker="#state_function">state function</seealso>
+ whenever a new state is entered; see
+ <seealso marker="#type-state_enter"><c>state_enter()</c></seealso>.
+ 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.
</p>
<note>
<p>If you in <c>gen_statem</c>, for example, postpone
@@ -527,6 +532,20 @@ handle_event(_, _, State, Data) ->
</desc>
</datatype>
<datatype>
+ <name name="callback_mode_result"/>
+ <desc>
+ <p>
+ This is the return type from
+ <seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso>
+ and selects
+ <seealso marker="#type-callback_mode">callback mode</seealso>
+ and whether to do
+ <seealso marker="#type-state_enter">state enter calls</seealso>,
+ or not.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
<name name="callback_mode"/>
<desc>
<p>
@@ -558,44 +577,48 @@ handle_event(_, _, State, Data) ->
</desc>
</datatype>
<datatype>
- <name name="state_entry_mode"/>
+ <name name="state_enter"/>
<desc>
<p>
- The <em>state entry mode</em> is selected when starting the
- <c>gen_statem</c> and after code change
- using the return value from
+ If the state machine should use <em>state enter calls</em>
+ is selected when starting the <c>gen_statem</c>
+ and after code change using the return value from
<seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso>.
</p>
<p>
If
<seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso>
- returns a list containing <c>state_entry_events</c>,
+ returns a list containing <c>state_enter</c>,
the <c>gen_statem</c> engine will, at every state change,
- insert an event of type
- <seealso marker="#type-event_type">enter</seealso>
- with content <c>OldState</c>. This event will be inserted
- before all other events such as those generated by
- <seealso marker="#type-action"><c>action()</c></seealso>
- <c>next_event</c>.
+ call the
+ <seealso marker="#state_function">state function</seealso>
+ with arguments <c>(enter, OldState, Data)</c>.
+ 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
+ <seealso marker="#Module:StateName/3"><c>Module:StateName/3</c></seealso>
+ and
+ <seealso marker="#Module:handle_event/4"><c>Module:handle_event/4</c></seealso>.
</p>
<p>
If
<seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso>
- does not return such a list, no state entry events are inserted.
+ does not return such a list, no state enter calls are done.
</p>
<p>
- No state entry event will be inserted after a
+ If
<seealso marker="#Module:code_change/4"><c>Module:code_change/4</c></seealso>
- 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.
</p>
<p>
- Note that a state entry event <em>will</em> be inserted
- when entering the initial state even though this formally
- is not a state change. In this case <c>OldState</c>
- will be the same as <c>State</c>, which can not happen
- for an actual state change.
+ Note that a state enter call <em>will</em> be done
+ right before entering the initial state even though this
+ formally is not a state change.
+ In this case <c>OldState</c> will be the same as <c>State</c>,
+ which can not happen for a subsequent state change.
</p>
</desc>
</datatype>
@@ -605,8 +628,7 @@ handle_event(_, _, State, Data) ->
<p>
Transition options can be set by
<seealso marker="#type-action">actions</seealso>
- and they modify the following in how
- the state transition is done:
+ and they modify how the state transition is done:
</p>
<list type="ordered">
<item>
@@ -636,17 +658,22 @@ handle_event(_, _, State, Data) ->
<seealso marker="#type-action"><c>action()</c></seealso>
<c>next_event</c>
are inserted in the queue to be processed before
- all other events.
+ other events.
</p>
</item>
<item>
<p>
- If the state changes or is the initial state, and the
- <seealso marker="#type-state_entry_mode"><em>state entry mode</em></seealso>
- is <c>state_entry_events</c>, an event of type
- <seealso marker="#type-event_type">enter</seealso>
- with content <c>OldState</c> is inserted
- to be processed before all other events including those above.
+ If the state changes or is the initial state, and
+ <seealso marker="#type-state_enter"><em>state enter calls</em></seealso>
+ are used, the <c>gen_statem</c> calls
+ the new state function with arguments
+ <seealso marker="#type-state_enter">(enter, OldState, Data)</seealso>.
+ If this call returns any
+ <seealso marker="#type-enter_action"><c>actions</c></seealso>
+ that sets transition options
+ they are merged with the current
+ That is: <c>hibernate</c> and <c>timeout</c> overrides
+ the current and <c>reply</c> sends a reply.
</p>
</item>
<item>
@@ -656,8 +683,9 @@ handle_event(_, _, State, Data) ->
is set through
<seealso marker="#type-action"><c>action()</c></seealso>
<c>timeout</c>,
- 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
+ <c>infinity</c> or a time-out zero event
+ is enqueued if the value is zero.
</p>
</item>
<item>
@@ -732,7 +760,7 @@ handle_event(_, _, State, Data) ->
is processed before any not yet received external event.
</p>
<p>
- 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.
</p>
</desc>
@@ -743,7 +771,10 @@ handle_event(_, _, State, Data) ->
<p>
These state transition actions can be invoked by
returning them from the
- <seealso marker="#state_function">state function</seealso>, from
+ <seealso marker="#state_function">state function</seealso>
+ when it is called with an
+ <seealso marker="#type-event_type">event</seealso>,
+ from
<seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
or by giving them to
<seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso>.
@@ -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
- <seealso marker="#type-event_timeout"><c>event_timeout()</c></seealso>
- overrides any other <c>event_timeout()</c> in the list.
+ <seealso marker="#type-postpone"><c>postpone()</c></seealso>
+ overrides any previous <c>postpone()</c> in the list.
</p>
<taglist>
<tag><c>postpone</c></tag>
@@ -775,6 +806,53 @@ handle_event(_, _, State, Data) ->
as there is no event to postpone in those cases.
</p>
</item>
+ <tag><c>next_event</c></tag>
+ <item>
+ <p>
+ Stores the specified <c><anno>EventType</anno></c>
+ and <c><anno>EventContent</anno></c> for insertion after all
+ actions have been executed.
+ </p>
+ <p>
+ 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 <c>next_event</c> in the containing
+ list becomes the first to process.
+ </p>
+ <p>
+ An event of type
+ <seealso marker="#type-event_type"><c>internal</c></seealso>
+ is to be used when you want to reliably distinguish
+ an event inserted this way from any external event.
+ </p>
+ </item>
+ </taglist>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="enter_action"/>
+ <desc>
+ <p>
+ These state transition actions can be invoked by
+ returning them from the
+ <seealso marker="#state_function">state function</seealso>, from
+ <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
+ or by giving them to
+ <seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso>.
+ </p>
+ <p>
+ Actions are executed in the containing list order.
+ </p>
+ <p>
+ Actions that set
+ <seealso marker="#type-transition_option">transition options</seealso>
+ override any previous of the same type,
+ so the last in the containing list wins.
+ For example, the last
+ <seealso marker="#type-event_timeout"><c>event_timeout()</c></seealso>
+ overrides any previous <c>event_timeout()</c> in the list.
+ </p>
+ <taglist>
<tag><c>hibernate</c></tag>
<item>
<p>
@@ -805,32 +883,6 @@ handle_event(_, _, State, Data) ->
to <c><anno>Time</anno></c> with <c><anno>EventContent</anno></c>.
</p>
</item>
- <tag><c>reply_action()</c></tag>
- <item>
- <p>
- Replies to a caller.
- </p>
- </item>
- <tag><c>next_event</c></tag>
- <item>
- <p>
- Stores the specified <c><anno>EventType</anno></c>
- and <c><anno>EventContent</anno></c> for insertion after all
- actions have been executed.
- </p>
- <p>
- 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 <c>next_event</c> in the containing
- list becomes the first to process.
- </p>
- <p>
- An event of type
- <seealso marker="#type-event_type"><c>internal</c></seealso>
- is to be used when you want to reliably distinguish
- an event inserted this way from any external event.
- </p>
- </item>
</taglist>
</desc>
</datatype>
@@ -838,13 +890,31 @@ handle_event(_, _, State, Data) ->
<name name="reply_action"/>
<desc>
<p>
- Replies to a caller waiting for a reply in
+ This state transition action can be invoked by
+ returning it from the
+ <seealso marker="#state_function">state function</seealso>, from
+ <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
+ or by giving it to
+ <seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso>.
+ </p>
+ <p>
+ It replies to a caller waiting for a reply in
<seealso marker="#call/2"><c>call/2</c></seealso>.
<c><anno>From</anno></c> must be the term from argument
<seealso marker="#type-event_type"><c>{call,<anno>From</anno>}</c></seealso>
- to the
+ in a call to a
<seealso marker="#state_function">state function</seealso>.
</p>
+ <p>
+ Note that using this action from
+ <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
+ or
+ <seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso>
+ would be weird on the border of whichcraft
+ since there has been no earlier call to a
+ <seealso marker="#state_function">state function</seealso>
+ in this server.
+ </p>
</desc>
</datatype>
<datatype>
@@ -869,6 +939,27 @@ handle_event(_, _, State, Data) ->
</desc>
</datatype>
<datatype>
+ <name name="state_function_enter_result"/>
+ <desc>
+ <taglist>
+ <tag><c>next_state</c></tag>
+ <item>
+ <p>
+ The <c>gen_statem</c> does a state transition to
+ <c><anno>NextStateName</anno></c>
+ (which can be the same as the current state),
+ sets <c><anno>NewData</anno></c>,
+ and executes all <c><anno>Actions</anno></c>.
+ </p>
+ </item>
+ </taglist>
+ <p>
+ All these terms are tuples or atoms and this property
+ will hold in any future version of <c>gen_statem</c>.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
<name name="handle_event_result"/>
<desc>
<taglist>
@@ -890,6 +981,27 @@ handle_event(_, _, State, Data) ->
</desc>
</datatype>
<datatype>
+ <name name="handle_event_enter_result"/>
+ <desc>
+ <taglist>
+ <tag><c>next_state</c></tag>
+ <item>
+ <p>
+ The <c>gen_statem</c> does a state transition to
+ <c><anno>NextState</anno></c>
+ (which can be the same as the current state),
+ sets <c><anno>NewData</anno></c>,
+ and executes all <c><anno>Actions</anno></c>.
+ </p>
+ </item>
+ </taglist>
+ <p>
+ All these terms are tuples or atoms and this property
+ will hold in any future version of <c>gen_statem</c>.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
<name name="common_state_callback_result"/>
<desc>
<taglist>
@@ -1148,10 +1260,11 @@ handle_event(_, _, State, Data) ->
<seealso marker="#type-event_type"><c>{call,<anno>From</anno>}</c></seealso>
to the
<seealso marker="#state_function">state function</seealso>.
- <c><anno>From</anno></c> and <c><anno>Reply</anno></c>
- can also be specified using a
- <seealso marker="#type-reply_action"><c>reply_action()</c></seealso>
- and multiple replies with a list of them.
+ A reply or multiple replies canalso be sent
+ using one or several
+ <seealso marker="#type-reply_action"><c>reply_action()</c></seealso>s
+ from a
+ <seealso marker="#state_function">state function</seealso>.
</p>
<note>
<p>
@@ -1362,7 +1475,8 @@ handle_event(_, _, State, Data) ->
once after server start and after code change,
but before the first
<seealso marker="#state_function">state function</seealso>
- 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 <c>gen_statem</c>.
</p>
<p>
@@ -1380,7 +1494,7 @@ handle_event(_, _, State, Data) ->
or a list containing
<seealso marker="#type-callback_mode">callback_mode()</seealso>
and possibly the atom
- <seealso marker="#type-state_entry_mode"><c>state_entry_events</c></seealso>.
+ <seealso marker="#type-state_enter"><c>state_enter</c></seealso>.
</p>
<note>
<p>
@@ -1601,7 +1715,8 @@ handle_event(_, _, State, Data) ->
</p>
<p>
The function is to return <c>Status</c>, 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 <c>gen_statem</c>. There are no restrictions on the
form <c>Status</c> can take, but for the
<seealso marker="sys#get_status/1"><c>sys:get_status/1,2</c></seealso>
@@ -1625,11 +1740,17 @@ handle_event(_, _, State, Data) ->
</func>
<func>
+ <name>Module:StateName(enter, OldState, Data) ->
+ StateFunctionEnterResult
+ </name>
<name>Module:StateName(EventType, EventContent, Data) ->
StateFunctionResult
</name>
- <name>Module:handle_event(EventType, EventContent,
- State, Data) -> HandleEventResult
+ <name>Module:handle_event(enter, OldState, State, Data) ->
+ HandleEventResult
+ </name>
+ <name>Module:handle_event(EventType, EventContent, State, Data) ->
+ HandleEventResult
</name>
<fsummary>Handle an event.</fsummary>
<type>
@@ -1651,9 +1772,17 @@ handle_event(_, _, State, Data) ->
<seealso marker="#type-state_function_result">state_function_result()</seealso>
</v>
<v>
+ StateFunctionEnterResult =
+ <seealso marker="#type-state_function_enter_result">state_function_enter_result()</seealso>
+ </v>
+ <v>
HandleEventResult =
<seealso marker="#type-handle_event_result">handle_event_result()</seealso>
</v>
+ <v>
+ HandleEventEnterResult =
+ <seealso marker="#type-handle_event_enter_result">handle_event_enter_result()</seealso>
+ </v>
</type>
<desc>
<p>
@@ -1695,6 +1824,24 @@ handle_event(_, _, State, Data) ->
see <seealso marker="#type-action"><c>action()</c></seealso>.
</p>
<p>
+ When the <c>gen_statem</c> runs with
+ <seealso marker="#type-state_enter">state enter calls</seealso>,
+ these functions are also called with arguments
+ <c>(enter, OldState, ...)</c> whenever the state changes.
+ In this case there are some restrictions on the
+ <seealso marker="#type-enter_action">actions</seealso>
+ that may be returned:
+ <seealso marker="#type-postpone"><c>postpone()</c></seealso>
+ and
+ <seealso marker="#type-action"><c>{next_event,_,_}</c></seealso>
+ are not allowed.
+ You may also not change states from this call.
+ Should you return <c>{next_state,NextState, ...}</c>
+ with <c>NextState =/= State</c> the <c>gen_statem</c> crashes.
+ You are advised to use <c>{keep_state,...}</c> or
+ <c>keep_state_and_data</c>.
+ </p>
+ <p>
Note the fact that you can use
<seealso marker="erts:erlang#throw/1"><c>throw</c></seealso>
to return the result, which can be useful.