From 61935c77915a8e206a82cba1c9c9f64be462905d Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 21 Jun 2018 09:53:55 +0200 Subject: Clean up and optimize code and doc --- lib/stdlib/doc/src/gen_statem.xml | 228 +++++++++++++++++++++----------------- 1 file changed, 124 insertions(+), 104 deletions(-) (limited to 'lib/stdlib/doc') 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

- The "state callback" for a specific + The state callback for a specific state in a gen_statem 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 callback mode is state_functions, the state must be an atom and - is used as the state callback name; see + is used as the state callback name; see Module:StateName/3. This co-locates all code for a specific state in one function as the gen_statem engine @@ -192,7 +192,7 @@ erlang:'!' -----> Module:StateName/3 When the callback mode is handle_event_function, the state can be any term - and the state callback name is + and the state callback name is Module:handle_event/4. 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.

- The gen_statem enqueues incoming events in order of arrival - and presents these to the - state callback - 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 gen_statem receives a process message it is + converted into an event and the + state callback + is called with the event as two arguments: type and content. + When the + state callback + has processed the event it returns to gen_statem + which does a state transition. + If this state transition is to a different state, + that is: NextState =/= State, it is a state change. +

+

+ The + state callback + may return + transition actions + for gen_statem + to execute during the state transition, + for example to reply to a + gen_statem:call/2,3. +

+

+ One of the possible transition actions + is to postpone the current event. + Then it is not retried in the current state. + The gen_statem engine keeps a queue of events + divided into the postponed events + and the events still to process. + After a state change the queue restarts + with the postponed events.

The gen_statem event queue model is sufficient @@ -215,13 +239,17 @@ erlang:'!' -----> Module:StateName/3 to entering a new receive statement.

- The state callback + The + state callback can insert events using the - action() + transition actions next_event - 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 + state callback + with. + That is, as if it is the oldest incoming event. + A dedicated event_type() internal can be used for such events making them impossible to mistake for external events. @@ -236,24 +264,26 @@ erlang:'!' -----> Module:StateName/3

The gen_statem engine can automatically make a specialized call to the - state callback + state callback 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 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 state transition, + and/or to use a dedicated state transition function, but that is something you will have to remember - at every state transition to the state(s) that need it. + at every state transition to the state(s) that need it.

If you in gen_statem, 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 state callback + of yours, you have not done a state change + and hence the postponed event is not retried, + which is logical but can be confusing.

- For the details of a state transition, see type + For the details of a state transition, see type transition_option().

@@ -276,7 +306,8 @@ erlang:'!' -----> Module:StateName/3 The gen_statem process can go into hibernation; see proc_lib:hibernate/3. It is done when a - state callback or + state callback + or Module:init/1 specifies hibernate in the returned Actions @@ -551,7 +582,7 @@ handle_event(_, _, State, Data) -> callback mode is handle_event_function, the state can be any term. - After a state change (NextState =/= State), + After a state change (NextState =/= State), all postponed events are retried.

@@ -564,7 +595,7 @@ handle_event(_, _, State, Data) -> callback mode is state_functions, the state must be of this type. - After a state change (NextState =/= State), + After a state change (NextState =/= State), all postponed events are retried.

@@ -595,7 +626,7 @@ handle_event(_, _, State, Data) ->

internal events can only be generated by the - state machine itself through the state transition action + state machine itself through the transition action next_event.

@@ -633,9 +664,9 @@ handle_event(_, _, State, Data) -> This is the return type from Module:callback_mode/0 and selects - callback mode + callback mode and whether to do - state enter calls, + state enter calls, or not.

@@ -684,13 +715,15 @@ handle_event(_, _, State, Data) -> If Module:callback_mode/0 returns a list containing state_enter, - the gen_statem engine will, at every state change, + the gen_statem engine will, at every state change, call the state callback with arguments (enter, OldState, Data). 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 + state callback + returned and before any event is delivered to the new + state callback. See Module:StateName/3 and @@ -703,27 +736,27 @@ handle_event(_, _, State, Data) -> repeat_state_and_data - tuple from the state callback. + tuple from the state callback.

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

If Module:code_change/4 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 state change, + which will not cause a state enter call.

- Note that a state enter call will be done + 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 cannot happen for a subsequent state change, - but will happen when repeating the state enter call. + actually is not a state change. + In this case OldState =:= State, + which can not happen for a subsequent state change, + but will happen when repeating the state enter call.

@@ -733,8 +766,11 @@ handle_event(_, _, State, Data) ->

Transition options can be set by actions - and modify the state transition. - Here are the sequence of steps for a state transition: + and modify the state transition. + The state transition takes place when the + state callback + has processed an event and returns. + Here are the sequence of steps for a state transition:

@@ -765,7 +801,7 @@ handle_event(_, _, State, Data) -> returned by the state callback that caused the state entry.

- Should this state enter call return any of + Should this state enter call return any of the mentioned repeat_* callback results it is repeated again, with the updated Data.

@@ -787,7 +823,8 @@ handle_event(_, _, State, Data) ->

- If the state changes, the queue of incoming events + If this is a state change, + the queue of incoming events is reset to start with the oldest postponed.

@@ -821,7 +858,7 @@ handle_event(_, _, State, Data) -> if the event queue is empty.

- A state change cancels a + A state change cancels a state_timeout() and any new transition option of this type belongs to the new state. @@ -830,7 +867,7 @@ handle_event(_, _, State, Data) ->

If there are enqueued events the - state callback + state callback 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 gen_statem, but if it is a system event it goes right back into hibernation. When a new message arrives the - state callback + state callback is called with the corresponding event, and we start again from the top of this sequence.

@@ -861,7 +898,7 @@ handle_event(_, _, State, Data) ->

If true, postpones the current event and retries - it when the state changes + it after a state change (NextState =/= State).

@@ -1021,9 +1058,9 @@ handle_event(_, _, State, Data) ->

- These state transition actions can be invoked by + These transition actions can be invoked by returning them from the - state callback + state callback when it is called with an event, from @@ -1054,7 +1091,7 @@ handle_event(_, _, State, Data) -> transition_option() postpone() - for this state transition. + for this state transition. This action is ignored when returned from Module:init/1 or given to @@ -1093,9 +1130,9 @@ handle_event(_, _, State, Data) ->

- These state transition actions can be invoked by + These transition actions can be invoked by returning them from the - state callback, from + state callback, from Module:init/1 or by giving them to enter_loop/5,6. @@ -1119,7 +1156,7 @@ handle_event(_, _, State, Data) -> Sets the transition_option() hibernate() - for this state transition. + for this state transition.

@@ -1129,9 +1166,9 @@ handle_event(_, _, State, Data) ->

- These state transition actions can be invoked by + These transition actions can be invoked by returning them from the - state callback, from + state callback, from Module:init/1 or by giving them to enter_loop/5,6. @@ -1147,7 +1184,7 @@ handle_event(_, _, State, Data) -> Short for {timeout,Time,Time}, that is, the time-out message is the time-out time. This form exists to make the - state callback + state callback return value {next_state,NextState,NewData,Time} allowed like for gen_fsm.

@@ -1193,9 +1230,9 @@ handle_event(_, _, State, Data) ->

- This state transition action can be invoked by + This transition action can be invoked by returning it from the - state callback, from + state callback, from Module:init/1 or by giving it to enter_loop/5,6. @@ -1210,7 +1247,7 @@ handle_event(_, _, State, Data) -> From must be the term from argument {call,From} in a call to a - state callback. + state callback.

Note that using this action from @@ -1219,7 +1256,7 @@ handle_event(_, _, State, Data) -> enter_loop/5,6 would be weird on the border of witchcraft since there has been no earlier call to a - state callback + state callback in this server.

@@ -1239,7 +1276,7 @@ handle_event(_, _, State, Data) -> The Actions are executed when entering the first state just as for a - state callback, + state callback, except that the action postpone is forced to false since there is no event to postpone.

@@ -1292,11 +1329,13 @@ handle_event(_, _, State, Data) -> next_state

- The gen_statem does a state transition to + The gen_statem does a state transition to NextState (which can be the same as the current state), sets NewData, and executes all Actions. + If NextState =/= CurrentState + the state transition is a state change.

@@ -1318,54 +1357,33 @@ handle_event(_, _, State, Data) -> keep_state

- The gen_statem keeps the current state, or - does a state transition to the current state if you like, - sets NewData, - and executes all Actions. - This is the same as + The same as {next_state,CurrentState,NewData,Actions}.

keep_state_and_data

- The gen_statem keeps the current state or - does a state transition to the current state if you like, - keeps the current server data, - and executes all Actions. - This is the same as - {next_state,CurrentState,CurrentData,Actions}. + The same as + {keep_state,CurrentData,Actions}.

repeat_state

- The gen_statem keeps the current state, or - does a state transition to the current state if you like, - sets NewData, - and executes all Actions. If the gen_statem runs with state enter calls, - the state enter call is repeated, see type + the state enter call is repeated, see type transition_option(), - otherwise repeat_state is the same as + other than that repeat_state is the same as keep_state.

repeat_state_and_data

- The gen_statem keeps the current state and data, or - does a state transition to the current state if you like, - and executes all Actions. - This is the same as + The same as {repeat_state,CurrentData,Actions}. - If the gen_statem runs with - state enter calls, - the state enter call is repeated, see type - transition_option(), - otherwise repeat_state_and_data is the same as - keep_state_and_data.

stop @@ -1408,14 +1426,15 @@ handle_event(_, _, State, Data) -> by sending a request and waiting until its reply arrives. The gen_statem calls the - state callback with + state callback + with event_type() {call,From} and event content Request.

A Reply is generated when a - state callback + state callback returns with {reply,From,Reply} as one action(), @@ -1484,7 +1503,8 @@ handle_event(_, _, State, Data) -> ignoring if the destination node or gen_statem does not exist. The gen_statem calls the - state callback with + state callback + with event_type() cast and event content Msg. @@ -1598,18 +1618,18 @@ handle_event(_, _, State, Data) -> call/2 when the reply cannot be defined in the return value of a - state callback. + state callback.

From must be the term from argument {call,From} to the - state callback. + state callback. A reply or multiple replies canalso be sent using one or several reply_action()s from a - state callback. + state callback.

@@ -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 - state callback + state callback in the current code version is called. More occasions may be added in future versions of gen_statem. @@ -1883,7 +1903,7 @@ handle_event(_, _, State, Data) ->

This callback is optional, so callback modules need not export it. If a release upgrade/downgrade with - Change={advanced,Extra} + Change = {advanced,Extra} specified in the .appup file is made when code_change/4 is not implemented the process will crash with exit reason undef. @@ -1893,7 +1913,7 @@ handle_event(_, _, State, Data) -> This function is called by a gen_statem when it is to update its internal state during a release upgrade/downgrade, that is, when the instruction {update,Module,Change,...}, - where Change={advanced,Extra}, is specified in the + where Change = {advanced,Extra}, is specified in the appup file. For more information, see OTP Design Principles. @@ -1933,13 +1953,13 @@ handle_event(_, _, State, Data) ->

Also note when upgrading a gen_statem, this function and hence - the Change={advanced,Extra} parameter in the + the Change = {advanced,Extra} parameter in the appup file is not only needed to update the internal state or to act on the Extra argument. It is also needed if an upgrade or downgrade should change callback mode, - or else the callback mode after the code change + or else the callback mode after the code change will not be honoured, most probably causing a server crash.

@@ -2148,7 +2168,7 @@ init(Args) -> erlang:error(not_implemented, [Args]). {call,From}, the caller waits for a reply. The reply can be sent from this or from any other - state callback + state callback by returning with {reply,From,Reply} in Actions, in Replies, @@ -2173,9 +2193,9 @@ init(Args) -> erlang:error(not_implemented, [Args]).

When the gen_statem runs with - state enter calls, + state enter calls, these functions are also called with arguments - (enter, OldState, ...) whenever the state changes. + (enter, OldState, ...) during every state change. In this case there are some restrictions on the actions that may be returned: -- cgit v1.2.3