diff options
Diffstat (limited to 'lib/stdlib/doc/src/gen_statem.xml')
-rw-r--r-- | lib/stdlib/doc/src/gen_statem.xml | 305 |
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. |