diff options
Diffstat (limited to 'lib/stdlib/doc/src/gen_statem.xml')
-rw-r--r-- | lib/stdlib/doc/src/gen_statem.xml | 228 |
1 files changed, 124 insertions, 104 deletions
diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index eb0f7d24f0..dfecd235c9 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -167,7 +167,7 @@ erlang:'!' -----> Module:StateName/3 </p> <marker id="state callback"/> <p> - The "<em>state callback</em>" for a specific + The <em>state callback</em> for a specific <seealso marker="#type-state">state</seealso> in a <c>gen_statem</c> is the callback function that is called for all events in this state. It is selected depending on which @@ -179,7 +179,7 @@ erlang:'!' -----> Module:StateName/3 When the <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> is <c>state_functions</c>, the state must be an atom and - is used as the state callback name; see + is used as the <em>state callback</em> name; see <seealso marker="#Module:StateName/3"><c>Module:StateName/3</c></seealso>. This co-locates all code for a specific state in one function as the <c>gen_statem</c> engine @@ -192,7 +192,7 @@ erlang:'!' -----> Module:StateName/3 When the <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> is <c>handle_event_function</c>, the state can be any term - and the state callback name is + and the <em>state callback</em> name is <seealso marker="#Module:handle_event/4"><c>Module:handle_event/4</c></seealso>. This makes it easy to branch depending on state or event as you desire. Be careful about which events you handle in which @@ -200,12 +200,36 @@ erlang:'!' -----> Module:StateName/3 forever creating an infinite busy loop. </p> <p> - The <c>gen_statem</c> enqueues incoming events in order of arrival - and presents these to the - <seealso marker="#state callback">state callback</seealso> - in that order. The state callback can postpone an event - so it is not retried in the current state. - After a state change the queue restarts with the postponed events. + When <c>gen_statem</c> receives a process message it is + converted into an event and the + <seealso marker="#state callback"><em>state callback</em></seealso> + is called with the event as two arguments: type and content. + When the + <seealso marker="#state callback"><em>state callback</em></seealso> + has processed the event it returns to <c>gen_statem</c> + which does a <em>state transition</em>. + If this <em>state transition</em> is to a different state, + that is: <c>NextState =/= State</c>, it is a <em>state change</em>. + </p> + <p> + The + <seealso marker="#state callback"><em>state callback</em></seealso> + may return + <seealso marker="#type-action"><em>transition actions</em></seealso> + for <c>gen_statem</c> + to execute during the <em>state transition</em>, + for example to reply to a + <seealso marker="#call/2"><c>gen_statem:call/2,3</c></seealso>. + </p> + <p> + One of the possible <em>transition actions</em> + is to postpone the current event. + Then it is not retried in the current state. + The <c>gen_statem</c> engine keeps a queue of events + divided into the postponed events + and the events still to process. + After a <em>state change</em> the queue restarts + with the postponed events. </p> <p> The <c>gen_statem</c> event queue model is sufficient @@ -215,13 +239,17 @@ erlang:'!' -----> Module:StateName/3 to entering a new receive statement. </p> <p> - The <seealso marker="#state callback">state callback</seealso> + The + <seealso marker="#state callback"><em>state callback</em></seealso> can insert events using the - <seealso marker="#type-action"><c>action()</c></seealso> + <seealso marker="#type-action"><em>transition actions</em></seealso> <c>next_event</c> - and such an event is inserted as the next to present - to the state callback. That is, as if it is - the oldest incoming event. A dedicated + and such an event is inserted in the event queue + as the next to call the + <seealso marker="#state callback"><em>state callback</em></seealso> + with. + That is, as if it is the oldest incoming event. + A dedicated <seealso marker="#type-event_type"><c>event_type()</c></seealso> <c>internal</c> can be used for such events making them impossible to mistake for external events. @@ -236,24 +264,26 @@ erlang:'!' -----> Module:StateName/3 <p> The <c>gen_statem</c> engine can automatically make a specialized call to the - <seealso marker="#state callback">state callback</seealso> + <seealso marker="#state callback"><em>state callback</em></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 an event at the state transition, - and/or to use a dedicated state transition function, + Another way to do it is to explicitly insert an event + at the <em>state transition</em>, + and/or to use a dedicated <em>state transition</em> function, but that is something you will have to remember - at every state transition to the state(s) that need it. + at every <em>state transition</em> to the state(s) that need it. </p> <note> <p>If you in <c>gen_statem</c>, for example, postpone - an event in one state and then call another state callback - of yours, you have not changed states and hence the postponed event - is not retried, which is logical but can be confusing. + an event in one state and then call another <em>state callback</em> + of yours, you have not done a <em>state change</em> + and hence the postponed event is not retried, + which is logical but can be confusing. </p> </note> <p> - For the details of a state transition, see type + For the details of a <em>state transition</em>, see type <seealso marker="#type-transition_option"><c>transition_option()</c></seealso>. </p> <p> @@ -276,7 +306,8 @@ erlang:'!' -----> Module:StateName/3 The <c>gen_statem</c> process can go into hibernation; see <seealso marker="proc_lib#hibernate/3"><c>proc_lib:hibernate/3</c></seealso>. It is done when a - <seealso marker="#state callback">state callback</seealso> or + <seealso marker="#state callback"><em>state callback</em></seealso> + or <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> specifies <c>hibernate</c> in the returned <seealso marker="#type-action"><c>Actions</c></seealso> @@ -551,7 +582,7 @@ handle_event(_, _, State, Data) -> <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> is <c>handle_event_function</c>, the state can be any term. - After a state change (<c>NextState =/= State</c>), + After a <em>state change</em> (<c>NextState =/= State</c>), all postponed events are retried. </p> </desc> @@ -564,7 +595,7 @@ handle_event(_, _, State, Data) -> <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> is <c>state_functions</c>, the state must be of this type. - After a state change (<c>NextState =/= State</c>), + After a <em>state change</em> (<c>NextState =/= State</c>), all postponed events are retried. </p> </desc> @@ -595,7 +626,7 @@ handle_event(_, _, State, Data) -> </p> <p> <c>internal</c> events can only be generated by the - state machine itself through the state transition action + state machine itself through the <em>transition action</em> <seealso marker="#type-action"><c>next_event</c></seealso>. </p> </desc> @@ -633,9 +664,9 @@ handle_event(_, _, State, Data) -> 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> + <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> and whether to do - <seealso marker="#type-state_enter">state enter calls</seealso>, + <seealso marker="#type-state_enter"><em>state enter calls</em></seealso>, or not. </p> </desc> @@ -684,13 +715,15 @@ handle_event(_, _, State, Data) -> If <seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso> returns a list containing <c>state_enter</c>, - the <c>gen_statem</c> engine will, at every state change, + the <c>gen_statem</c> engine will, at every <em>state change</em>, call the <seealso marker="#state callback">state callback</seealso> with arguments <c>(enter, OldState, Data)</c>. This may look like an event but is really a call - performed after the previous state callback returned - and before any event is delivered to the new state callback. + performed after the previous + <seealso marker="#state callback"><em>state callback</em></seealso> + returned and before any event is delivered to the new + <seealso marker="#state callback"><em>state callback</em></seealso>. See <seealso marker="#Module:StateName/3"><c>Module:StateName/3</c></seealso> and @@ -703,27 +736,27 @@ handle_event(_, _, State, Data) -> <seealso marker="#type-state_callback_result"> <c>repeat_state_and_data</c> </seealso> - tuple from the state callback. + tuple from the <em>state callback</em>. </p> <p> If <seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso> - does not return such a list, no state enter calls are done. + does not return such a list, no <em>state enter calls</em> are done. </p> <p> If <seealso marker="#Module:code_change/4"><c>Module:code_change/4</c></seealso> should transform the state, - it is regarded as a state rename and not a state change, - which will not cause a state enter call. + it is regarded as a state rename and not a <em>state change</em>, + which will not cause a <em>state enter call</em>. </p> <p> - Note that a state enter call <em>will</em> be done + Note that a <em>state enter call</em> <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 cannot happen for a subsequent state change, - but will happen when repeating the state enter call. + actually is not a <em>state change</em>. + In this case <c>OldState =:= State</c>, + which can not happen for a subsequent state change, + but will happen when repeating the <em>state enter call</em>. </p> </desc> </datatype> @@ -733,8 +766,11 @@ handle_event(_, _, State, Data) -> <p> Transition options can be set by <seealso marker="#type-action">actions</seealso> - and modify the state transition. - Here are the sequence of steps for a state transition: + and modify the <em>state transition</em>. + The <em>state transition</em> takes place when the + <seealso marker="#state callback"><em>state callback</em></seealso> + has processed an event and returns. + Here are the sequence of steps for a <em>state transition</em>: </p> <list type="ordered"> <item> @@ -765,7 +801,7 @@ handle_event(_, _, State, Data) -> returned by the state callback that caused the state entry. </p> <p> - Should this state enter call return any of + Should this <em>state enter call</em> return any of the mentioned <c>repeat_*</c> callback results it is repeated again, with the updated <c>Data</c>. </p> @@ -787,7 +823,8 @@ handle_event(_, _, State, Data) -> </item> <item> <p> - If the state changes, the queue of incoming events + If this is a <em>state change</em>, + the queue of incoming events is reset to start with the oldest postponed. </p> </item> @@ -821,7 +858,7 @@ handle_event(_, _, State, Data) -> if the event queue is empty. </p> <p> - A state change cancels a + A <em>state change</em> cancels a <seealso marker="#type-state_timeout"><c>state_timeout()</c></seealso> and any new transition option of this type belongs to the new state. @@ -830,7 +867,7 @@ handle_event(_, _, State, Data) -> <item> <p> If there are enqueued events the - <seealso marker="#state callback">state callback</seealso> + <seealso marker="#state callback"><em>state callback</em></seealso> for the possibly new state is called with the oldest enqueued event, and we start again from the top of this list. @@ -848,7 +885,7 @@ handle_event(_, _, State, Data) -> the next incoming message awakens the <c>gen_statem</c>, but if it is a system event it goes right back into hibernation. When a new message arrives the - <seealso marker="#state callback">state callback</seealso> + <seealso marker="#state callback"><em>state callback</em></seealso> is called with the corresponding event, and we start again from the top of this sequence. </p> @@ -861,7 +898,7 @@ handle_event(_, _, State, Data) -> <desc> <p> If <c>true</c>, postpones the current event and retries - it when the state changes + it after a <em>state change</em> (<c>NextState =/= State</c>). </p> </desc> @@ -1021,9 +1058,9 @@ handle_event(_, _, State, Data) -> <name name="action"/> <desc> <p> - These state transition actions can be invoked by + These <em>transition actions</em> can be invoked by returning them from the - <seealso marker="#state callback">state callback</seealso> + <seealso marker="#state callback"><em>state callback</em></seealso> when it is called with an <seealso marker="#type-event_type">event</seealso>, from @@ -1054,7 +1091,7 @@ handle_event(_, _, State, Data) -> <c>transition_option()</c> </seealso> <seealso marker="#type-postpone"><c>postpone()</c></seealso> - for this state transition. + for this <em>state transition</em>. This action is ignored when returned from <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> or given to @@ -1093,9 +1130,9 @@ handle_event(_, _, State, Data) -> <name name="enter_action"/> <desc> <p> - These state transition actions can be invoked by + These <em>transition actions</em> can be invoked by returning them from the - <seealso marker="#state callback">state callback</seealso>, from + <seealso marker="#state callback"><em>state callback</em></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>. @@ -1119,7 +1156,7 @@ handle_event(_, _, State, Data) -> Sets the <seealso marker="#type-transition_option"><c>transition_option()</c></seealso> <seealso marker="#type-hibernate"><c>hibernate()</c></seealso> - for this state transition. + for this <em>state transition</em>. </p> </item> </taglist> @@ -1129,9 +1166,9 @@ handle_event(_, _, State, Data) -> <name name="timeout_action"/> <desc> <p> - These state transition actions can be invoked by + These <em>transition actions</em> can be invoked by returning them from the - <seealso marker="#state callback">state callback</seealso>, from + <seealso marker="#state callback"><em>state callback</em></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>. @@ -1147,7 +1184,7 @@ handle_event(_, _, State, Data) -> Short for <c>{timeout,Time,Time}</c>, that is, the time-out message is the time-out time. This form exists to make the - <seealso marker="#state callback">state callback</seealso> + <seealso marker="#state callback"><em>state callback</em></seealso> return value <c>{next_state,NextState,NewData,Time}</c> allowed like for <c>gen_fsm</c>. </p> @@ -1193,9 +1230,9 @@ handle_event(_, _, State, Data) -> <name name="reply_action"/> <desc> <p> - This state transition action can be invoked by + This <em>transition action</em> can be invoked by returning it from the - <seealso marker="#state callback">state callback</seealso>, from + <seealso marker="#state callback"><em>state callback</em></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>. @@ -1210,7 +1247,7 @@ handle_event(_, _, State, Data) -> <c><anno>From</anno></c> must be the term from argument <seealso marker="#type-event_type"><c>{call,<anno>From</anno>}</c></seealso> in a call to a - <seealso marker="#state callback">state callback</seealso>. + <seealso marker="#state callback"><em>state callback</em></seealso>. </p> <p> Note that using this action from @@ -1219,7 +1256,7 @@ handle_event(_, _, State, Data) -> <seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso> would be weird on the border of witchcraft since there has been no earlier call to a - <seealso marker="#state callback">state callback</seealso> + <seealso marker="#state callback"><em>state callback</em></seealso> in this server. </p> </desc> @@ -1239,7 +1276,7 @@ handle_event(_, _, State, Data) -> The <seealso marker="#type-action"><c>Actions</c></seealso> are executed when entering the first <seealso marker="#type-state">state</seealso> just as for a - <seealso marker="#state callback">state callback</seealso>, + <seealso marker="#state callback"><em>state callback</em></seealso>, except that the action <c>postpone</c> is forced to <c>false</c> since there is no event to postpone. </p> @@ -1292,11 +1329,13 @@ handle_event(_, _, State, Data) -> <tag><c>next_state</c></tag> <item> <p> - The <c>gen_statem</c> does a state transition to + The <c>gen_statem</c> does a <em>state transition</em> 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>. + If <c><anno>NextState</anno> =/= CurrentState</c> + the <em>state transition</em> is a <em>state change</em>. </p> </item> </taglist> @@ -1318,54 +1357,33 @@ handle_event(_, _, State, Data) -> <tag><c>keep_state</c></tag> <item> <p> - The <c>gen_statem</c> keeps the current state, or - does a state transition to the current state if you like, - sets <c><anno>NewData</anno></c>, - and executes all <c><anno>Actions</anno></c>. - This is the same as + The same as <c>{next_state,CurrentState,<anno>NewData</anno>,<anno>Actions</anno>}</c>. </p> </item> <tag><c>keep_state_and_data</c></tag> <item> <p> - The <c>gen_statem</c> keeps the current state or - does a state transition to the current state if you like, - keeps the current server data, - and executes all <c><anno>Actions</anno></c>. - This is the same as - <c>{next_state,CurrentState,CurrentData,<anno>Actions</anno>}</c>. + The same as + <c>{keep_state,CurrentData,<anno>Actions</anno>}</c>. </p> </item> <tag><c>repeat_state</c></tag> <item> <p> - The <c>gen_statem</c> keeps the current state, or - does a state transition to the current state if you like, - sets <c><anno>NewData</anno></c>, - and executes all <c><anno>Actions</anno></c>. If the <c>gen_statem</c> runs with <seealso marker="#type-state_enter"><em>state enter calls</em></seealso>, - the state enter call is repeated, see type + the <em>state enter call</em> is repeated, see type <seealso marker="#type-transition_option"><c>transition_option()</c></seealso>, - otherwise <c>repeat_state</c> is the same as + other than that <c>repeat_state</c> is the same as <c>keep_state</c>. </p> </item> <tag><c>repeat_state_and_data</c></tag> <item> <p> - The <c>gen_statem</c> keeps the current state and data, or - does a state transition to the current state if you like, - and executes all <c><anno>Actions</anno></c>. - This is the same as + The same as <c>{repeat_state,CurrentData,<anno>Actions</anno>}</c>. - If the <c>gen_statem</c> runs with - <seealso marker="#type-state_enter"><em>state enter calls</em></seealso>, - the state enter call is repeated, see type - <seealso marker="#type-transition_option"><c>transition_option()</c></seealso>, - otherwise <c>repeat_state_and_data</c> is the same as - <c>keep_state_and_data</c>. </p> </item> <tag><c>stop</c></tag> @@ -1408,14 +1426,15 @@ handle_event(_, _, State, Data) -> by sending a request and waiting until its reply arrives. The <c>gen_statem</c> calls the - <seealso marker="#state callback">state callback</seealso> with + <seealso marker="#state callback"><em>state callback</em></seealso> + with <seealso marker="#type-event_type"><c>event_type()</c></seealso> <c>{call,From}</c> and event content <c><anno>Request</anno></c>. </p> <p> A <c><anno>Reply</anno></c> is generated when a - <seealso marker="#state callback">state callback</seealso> + <seealso marker="#state callback"><em>state callback</em></seealso> returns with <c>{reply,From,<anno>Reply</anno>}</c> as one <seealso marker="#type-action"><c>action()</c></seealso>, @@ -1484,7 +1503,8 @@ handle_event(_, _, State, Data) -> ignoring if the destination node or <c>gen_statem</c> does not exist. The <c>gen_statem</c> calls the - <seealso marker="#state callback">state callback</seealso> with + <seealso marker="#state callback"><em>state callback</em></seealso> + with <seealso marker="#type-event_type"><c>event_type()</c></seealso> <c>cast</c> and event content <c><anno>Msg</anno></c>. @@ -1598,18 +1618,18 @@ handle_event(_, _, State, Data) -> <seealso marker="#call/2"><c>call/2</c></seealso> when the reply cannot be defined in the return value of a - <seealso marker="#state callback">state callback</seealso>. + <seealso marker="#state callback"><em>state callback</em></seealso>. </p> <p> <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 - <seealso marker="#state callback">state callback</seealso>. + <seealso marker="#state callback"><em>state callback</em></seealso>. 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 callback">state callback</seealso>. + <seealso marker="#state callback"><em>state callback</em></seealso>. </p> <note> <p> @@ -1826,7 +1846,7 @@ handle_event(_, _, State, Data) -> for efficiency reasons, so this function is only called once after server start and after code change, but before the first - <seealso marker="#state callback">state callback</seealso> + <seealso marker="#state callback"><em>state callback</em></seealso> in the current code version is called. More occasions may be added in future versions of <c>gen_statem</c>. @@ -1883,7 +1903,7 @@ handle_event(_, _, State, Data) -> <p> This callback is optional, so callback modules need not export it. If a release upgrade/downgrade with - <c>Change={advanced,Extra}</c> + <c>Change = {advanced,Extra}</c> specified in the <c>.appup</c> file is made when <c>code_change/4</c> is not implemented the process will crash with exit reason <c>undef</c>. @@ -1893,7 +1913,7 @@ handle_event(_, _, State, Data) -> This function is called by a <c>gen_statem</c> when it is to update its internal state during a release upgrade/downgrade, that is, when the instruction <c>{update,Module,Change,...}</c>, - where <c>Change={advanced,Extra}</c>, is specified in the + where <c>Change = {advanced,Extra}</c>, is specified in the <seealso marker="sasl:appup"><c>appup</c></seealso> file. For more information, see <seealso marker="doc/design_principles:release_handling#instr">OTP Design Principles</seealso>. @@ -1933,13 +1953,13 @@ handle_event(_, _, State, Data) -> <p> Also note when upgrading a <c>gen_statem</c>, this function and hence - the <c>Change={advanced,Extra}</c> parameter in the + the <c>Change = {advanced,Extra}</c> parameter in the <seealso marker="sasl:appup"><c>appup</c></seealso> file is not only needed to update the internal state or to act on the <c>Extra</c> argument. It is also needed if an upgrade or downgrade should change <seealso marker="#type-callback_mode"><em>callback mode</em></seealso>, - or else the callback mode after the code change + or else the <em>callback mode</em> after the code change will not be honoured, most probably causing a server crash. </p> @@ -2148,7 +2168,7 @@ init(Args) -> erlang:error(not_implemented, [Args]).</pre> <seealso marker="#type-event_type"><c>{call,From}</c></seealso>, the caller waits for a reply. The reply can be sent from this or from any other - <seealso marker="#state callback">state callback</seealso> + <seealso marker="#state callback"><em>state callback</em></seealso> by returning with <c>{reply,From,Reply}</c> in <seealso marker="#type-action"><c>Actions</c></seealso>, in <seealso marker="#type-reply_action"><c>Replies</c></seealso>, @@ -2173,9 +2193,9 @@ init(Args) -> erlang:error(not_implemented, [Args]).</pre> </p> <p> When the <c>gen_statem</c> runs with - <seealso marker="#type-state_enter">state enter calls</seealso>, + <seealso marker="#type-state_enter"><em>state enter calls</em></seealso>, these functions are also called with arguments - <c>(enter, OldState, ...)</c> whenever the state changes. + <c>(enter, OldState, ...)</c> during every <em>state change</em>. In this case there are some restrictions on the <seealso marker="#type-enter_action">actions</seealso> that may be returned: |