From 09d138e229846b7056331151135b7c8a52dc476f Mon Sep 17 00:00:00 2001 From: xsipewe Date: Fri, 6 May 2016 09:55:25 +0200 Subject: Editorial update --- lib/stdlib/doc/src/gen_statem.xml | 1723 +++++++++++++++++++------------------ 1 file changed, 895 insertions(+), 828 deletions(-) (limited to 'lib/stdlib') diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index ec7f267c64..4fe940bd05 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -29,39 +29,49 @@ gen_statem - Generic State Machine Behaviour + Generic state machine behavior.

- A behaviour module for implementing a state machine. Two + This behavior module provides a state machine. Two callback modes - are supported. One for finite state machines - (gen_fsm like) - that requires the state to be an atom and uses that state as - the name of the current callback function, - and one without restriction on the state data type - that uses one callback function for all states. -

-

- This is a new behaviour in 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. - But depending on user feedback, we do not expect - but might find it necessary to make minor - not backwards compatible changes into OTP-20.0, - so its state can be designated as "not quite experimental"... + are supported:

+ + +

One for finite-state machines + (gen_fsm like), + which requires the state to be an atom and uses that state as + the name of the current callback function +

+
+ +

One without restriction on the state data type + that uses one callback function for all states +

+
+
+ +

+ 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. + 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. +

+

- The gen_statem behaviour is intended to replace + The gen_statem behavior is intended to replace gen_fsm for new code. - It has the same features and add some really useful: + It has the same features and adds some really useful:

- State code is gathered - The state can be any term - Events can be postponed - Events can be self generated - A reply can be sent from a later state - There can be multiple sys traceable replies + State code is gathered. + The state can be any term. + Events can be postponed. + Events can be self-generated. + A reply can be sent from a later state. + There can be multiple sys traceable replies.

The callback model(s) for gen_statem differs from @@ -71,19 +81,18 @@

A generic state machine process (gen_statem) implemented - using this module will have a standard set of interface functions - and include functionality for tracing and error reporting. - It will also fit into an OTP supervision tree. Refer to + using this module has a standard set of interface functions + and includes functionality for tracing and error reporting. + It also fits into an OTP supervision tree. For more information, see OTP Design Principles - - for more information. + .

A gen_statem assumes all specific parts to be located in a - callback module exporting a pre-defined set of functions. - The relationship between the behaviour functions and the callback - functions can be illustrated as follows:

+ callback module exporting a predefined set of functions. + The relationship between the behavior functions and the callback + functions is as follows:

 gen_statem module            Callback module
 -----------------            ---------------
@@ -103,37 +112,37 @@ erlang:'!'            -----> Module:StateName/3
 -                     -----> Module:code_change/4

Events are of different - types + types, so the callback functions can know the origin of an event and how to respond.

If a callback function fails or returns a bad value, - the gen_statem will terminate. An exception of class - throw, - however, is not regarded as an error but as a valid return. + the gen_statem terminates. However, an exception of class + throw + is not regarded as an error but as a valid return.

- +

The "state function" for a specific state in a gen_statem is the callback function that is called - for all events in this state, and is selected depending on which + for all events in this state. It is selected depending on which callback mode - that the implementation specifies when the the server starts. + that the implementation specifies when the server starts.

When the callback mode - is state_functions, the state has to be an atom and - is used as the state function name. See + is state_functions, the state must be an atom and + is used as the state function name; see Module:StateName/3 . This gathers all code for a specific state in one function and hence dispatches on state first. - Note that in this mode the fact that there is - a mandatory callback function + Notice that in this mode + the mandatory callback function Module:terminate/3 makes the state name terminate unusable. @@ -141,21 +150,21 @@ erlang:'!' -----> Module:StateName/3

When the callback mode - is handle_event_function the state can be any term + is handle_event_function, the state can be any term and the state function name is Module:handle_event/4 . This makes it easy to dispatch on state or on event as you desire. Be careful about which events you handle in which - states so you do not accidentally postpone one event + states so that you do not accidentally postpone one event forever creating an infinite busy loop.

The gen_statem enqueues incoming events in order of arrival and presents these to the state function - in that order. The state function can postpone an event + in that order. The state function can postpone an event so it is not retried in the current state. After a state change the queue restarts with the postponed events.

@@ -163,7 +172,7 @@ erlang:'!' -----> Module:StateName/3 The gen_statem event queue model is sufficient to emulate the normal process message queue with selective receive. Postponing an event corresponds to not matching it - in a receive statement and changing states corresponds + in a receive statement, and changing states corresponds to entering a new receive statement.

@@ -173,73 +182,76 @@ erlang:'!' -----> Module:StateName/3 action() next_event and such an event is inserted as the next to present - to the state function. That is: as if it is - the oldest incoming event. There is a dedicated + to the state function. That is, as if it is + the oldest incoming event. A dedicated event_type() - internal that can be used for such events making them impossible + internal can be used for such events making them impossible to mistake for external events.

Inserting an event replaces the trick of calling your own state handling functions that you often would have to - resort to in for example gen_fsm + resort to in, for example, + gen_fsm to force processing an inserted event before others. - A warning, though: if you in gen_statem for example - postpone an event in one state and then call some other state function of yours, - you have not changed states and hence the postponed event will not be retried, - which is logical but might be confusing.

+ +

If you in gen_statem, for example, postpone + an event in one state and then call another state function + of yours, you have not changed states and hence the postponed event + is not retried, which is logical but can be confusing. +

+

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

- A gen_statem handles system messages as documented in + A gen_statem handles system messages as described in sys. The sysmodule can be used for debugging a gen_statem.

- Note that a gen_statem does not trap exit signals + Notice that a gen_statem does not trap exit signals automatically, this must be explicitly initiated in the callback module (by calling - process_flag(trap_exit, true). + process_flag(trap_exit, true).

Unless otherwise stated, all functions in this module fail if the specified gen_statem does not exist or - if bad arguments are given. + if bad arguments are specified.

The gen_statem process can go into hibernation; see - proc_lib:hibernate/3. - + proc_lib:hibernate/3 + . It is done when a state function or Module:init/1 specifies hibernate in the returned Actions - list. This feature might be useful to reclaim process heap memory + list. This feature can be useful to reclaim process heap memory while the server is expected to be idle for a long time. - However, use this feature with care - since hibernation can be too costly + However, use this feature with care, + as hibernation can be too costly to use after every event; see - erlang:hibernate/3. - + erlang:hibernate/3 + .

- EXAMPLE + Example

- This example shows a simple pushbutton model + The following example shows a simple pushbutton model for a toggling pushbutton implemented with callback mode state_functions. @@ -247,7 +259,8 @@ erlang:'!' -----> Module:StateName/3 and you can ask for a count of how many times it has been pushed to on.

-

This is the complete callback module file pushbutton.erl:

+

The following is the complete callback module file + pushbutton.erl:

-module(pushbutton). -behaviour(gen_statem). @@ -305,7 +318,7 @@ handle_event(_, _, Data) -> %% Ignore all other events {keep_state,Data}. -

And this is a shell session when running it:

+

The following is a shell session when running it:

 1> pushbutton:start().
 {ok,<0.36.0>}
@@ -326,12 +339,11 @@ ok
      in function  gen:do_for_proc/2 (gen.erl, line 261)
      in call from gen_statem:call/3 (gen_statem.erl, line 386)
     
-

- And just to compare styles here is the same example using + To compare styles, here follows the same example using callback mode - state_functions, or rather here is code to replace - from the init/1 function of the pushbutton.erl + state_functions, or rather the code to replace + from function init/1 of the pushbutton.erl example file above:

@@ -364,11 +376,11 @@ handle_event(_, _, State, Data) -> - +

Name specification to use when starting - a gen_statem server. See + a gen_statem server. See start_link/3 @@ -380,7 +392,7 @@ handle_event(_, _, State, Data) -> - +

Server specification to use when addressing @@ -393,75 +405,83 @@ handle_event(_, _, State, Data) ->

It can be:

- pid()
- LocalName
- The gen_statem is locally registered. + pid() | LocalName + +

+ The gen_statem is locally registered. +

+
Name, Node - The gen_statem is locally registered - on another node. +

+ The gen_statem is locally registered + on another node. +

GlobalName - The gen_statem is globally registered - in global. +

+ The gen_statem is globally registered + in kernel:global. +

RegMod, ViaName - The gen_statem is registered through - an alternative process registry. - The registry callback module RegMod - should export the functions - register_name/2, unregister_name/1, - whereis_name/1 and send/2, - which should behave like the corresponding functions - in global. - Thus, {via,global,GlobalName} is the same as - {global,GlobalName}. +

+ The gen_statem is registered through + an alternative process registry. + The registry callback module RegMod + is to export functions + register_name/2, unregister_name/1, + whereis_name/1, and send/2, + which are to behave like the corresponding functions + in kernel:global. + Thus, {via,global,GlobalName} is the same as + {global,GlobalName}. +

- +

Debug option that can be used when starting - a gen_statem server through for example + a gen_statem server through, for example, enter_loop/5.

- For every entry in Dbgs + For every entry in Dbgs, the corresponding function in - sys will be called. + sys is called.

- +

Options that can be used when starting - a gen_statem server through for example + a gen_statem server through, for example, start_link/3.

- +

- Return value from the start functions for_example + Return value from the start functions, for example, start_link/3.

- - +

- Destination to use when replying through for example the + Destination to use when replying through, for example, the action() @@ -472,178 +492,194 @@ handle_event(_, _, State, Data) -> - +

- After a state change (NextState =/= State) + After a state change (NextState =/= State), all postponed events are retried.

- +

If the callback mode is state_functions, - the state has to be of this type. + the state must be of this type.

- +

A term in which the state machine implementation - should store any server data it needs. The difference between + is to store any server data it needs. The difference between this and the state() itself is that a change in this data does not cause - postponed events to be retried. Hence if a change + postponed events to be retried. Hence, if a change in this data would change the set of events that - are handled than that data item should be made + are handled, then that data item is to be made a part of the state.

- +

- External events are of 3 different type: - {call,From}, cast or info. + External events are of three types: + {call,From}, cast, or info. Calls (synchronous) and casts originate from the corresponding API functions. - For calls the event contain whom to reply to. + For calls, the event contains whom to reply to. Type info originates from regular process messages sent - to the gen_statem. It is also possible for the state machine - implementation to generate events of types + to the gen_statem. Also, the state machine + implementation can generate events of types timeout and internal to itself.

- +

The callback mode is selected when starting the gen_statem using the return value from Module:init/1 or when calling - enter_loop/5-7, + enter_loop/5,6,7, and with the return value from - Module:code_change/4. - + Module:code_change/4 + .

state_functions - The state has to be of type - state_name() - and one callback function per state that is - - Module:StateName/3 - - is used. +

+ The state must be of type + state_name() + and one callback function per state, that is, + + Module:StateName/3 + , + is used. +

handle_event_function - The state can be any term and the callback function - - Module:handle_event/4 - - is used for all states. +

+ The state can be any term and the callback function + + Module:handle_event/4 + + is used for all states. +

- +

- Transition options may be set by + Transition options can be set by actions - and they modify some details below in how + and they modify the following in how the state transition is done:

- All - actions - are processed in order of appearance. +

+ All + actions + are processed in order of appearance. +

- If - - postpone() - - is true - the current event is postponed. +

+ If + + postpone() + + is true, + the current event is postponed. +

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

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

- All events stored with - - action() - - next_event - are inserted in the queue to be processed before - all other events. +

+ All events stored with + + action() + + next_event + are inserted in the queue to be processed before + all other events. +

- If an - - event_timeout() - - is set through - - action() - - timeout - an event timer may be started or a timeout zero event - may be enqueued. +

+ If an + + event_timeout() + + is set through + + action() + + timeout, + an event timer can be started or a time-out zero event + can be enqueued. +

- The (possibly new) - state function - is called with the oldest enqueued event if there is any, - otherwise the gen_statem goes into receive - or hibernation - (if - - hibernate() - - is true) - to wait for the next message. In hibernation the next - non-system event awakens the gen_statem, or rather - the next incoming message awakens the gen_statem - but if it is a system event - it goes right back into hibernation. +

+ The (possibly new) + state function + is called with the oldest enqueued event if there is any, + otherwise the gen_statem goes into receive + or hibernation + (if + + hibernate() + + is true) + to wait for the next message. In hibernation the next + non-system event awakens the gen_statem, or rather + the next incoming message awakens the gen_statem, + but if it is a system event + it goes right back into hibernation. +

- +

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

- +

- If true hibernate the gen_statem + If true, hibernates the gen_statem by calling proc_lib:hibernate/3 @@ -651,9 +687,9 @@ handle_event(_, _, State, Data) -> before going into receive to wait for a new external event. If there are enqueued events, - to prevent receiving any new event; a + to prevent receiving any new event, an - garbage_collect/0 + erlang:garbage_collect/0 is done instead to simulate that the gen_statem entered hibernation and immediately got awakened by the oldest enqueued event. @@ -661,39 +697,39 @@ handle_event(_, _, State, Data) -> - +

- Generate an event of + Generates an event of event_type() timeout - after this time (in milliseconds) unless some other - event arrives in which case this timeout is cancelled. - Note that a retried or inserted event - counts just like a new in this respect. + after this time (in milliseconds) unless another + event arrives in which case this time-out is cancelled. + Notice that a retried or inserted event + counts like a new in this respect.

- If the value is infinity no timer is started since - it will never trigger anyway. + If the value is infinity, no timer is started, as + it never triggers anyway.

- If the value is 0 the timeout event is immediately enqueued - unless there already are enqueued events since then the - timeout is immediately cancelled. - This is a feature ensuring that a timeout 0 event - will be processed before any not yet received external event. + If the value is 0, the time-out event is immediately enqueued + unless there already are enqueued events, as the + time-out is then immediately cancelled. + This is a feature ensuring that a time-out 0 event + is processed before any not yet received external event.

- Note that it is not possible nor needed to cancel this timeout - since it is cancelled automatically by any other event. + Notice that it is not possible or needed to cancel this time-out, + as it is cancelled automatically by any other event.

- +

- These state transition actions may be invoked by + These state transition actions can be invoked by returning them from the state function, from Module:init/1 @@ -708,9 +744,9 @@ handle_event(_, _, State, Data) -> transition options - overrides any previous of the same type, + override any previous of the same type, so the last in the containing list wins. - For example the last + For example, the last event_timeout() @@ -719,77 +755,87 @@ handle_event(_, _, State, Data) -> postpone - Set the - - transition_option() - - - postpone() - - for this state transition. - This action is ignored when returned from - Module:init/1 - or given to - enter_loop/5,6 - since there is no event to postpone in those cases. +

+ Sets the + + transition_option() + + + postpone() + + for this state transition. + This action is ignored when returned from + Module:init/1 + or given to + enter_loop/5,6, + as there is no event to postpone in those cases. +

hibernate - Set the - - transition_option() - - - hibernate() - - for this state transition. +

+ Sets the + + transition_option() + + + hibernate() + + for this state transition. +

Timeout - Short for {timeout,Timeout,Timeout} that is - the timeout message is the timeout time. - This form exists to make the - state function - return value {next_state,NextState,NewData,Timeout} - allowed like for - - gen_fsm Module:StateName/2. - +

+ Short for {timeout,Timeout,Timeout}, that is, + the time-out message is the time-out time. + This form exists to make the + state function + return value {next_state,NextState,NewData,Timeout} + allowed like for + + gen_fsm:Module:StateName/2 + . +

timeout - Set the - - transition_option() - - - event_timeout() - - to Time with EventContent. +

+ Sets the + + transition_option() + + + event_timeout() + + to Time with EventContent. +

reply_action() - Reply to a caller. + +

+ Replies to a caller. +

+
next_event - Store the given EventType +

+ 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 - will become the first 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 - should be used when you want to reliably distinguish + is to be used when you want to reliably distinguish an event inserted this way from any external event.

@@ -797,294 +843,125 @@ handle_event(_, _, State, Data) ->
- +

- Reply to a caller waiting for a reply in + Replies to a caller waiting for a reply in call/2. - From must be the term from the + From must be the term from argument {call,From} - argument to the + to the state function.

- + next_state - The gen_statem will do a state transition to - NextStateName - (which may be the same as the current state), - set NewData - and execute all Actions +

+ 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, - just in case you need such a promise. + will hold in any future version of gen_statem.

- + next_state - The gen_statem will do a state transition to - NextState - (which may be the same as the current state), - set NewData - and execute all Actions +

+ 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, - just in case you need such a promise. + will hold in any future version of gen_statem.

- + stop - Terminate the gen_statem by calling - - Module:terminate/3 - - with Reason and - NewData, if given. +

+ Terminates the gen_statem by calling + + Module:terminate/3 + + with Reason and + NewData, if specified. +

stop_and_reply - Send all Replies - then terminate the gen_statem by calling - - Module:terminate/3 - - with Reason and - NewData, if given. +

+ Sends all Replies, + then terminates the gen_statem by calling + + Module:terminate/3 + + with Reason and + NewData, if specified. +

keep_state - The gen_statem will keep the current state, or - do a state transition to the current state if you like, - set NewData - and execute all Actions. - This is the same as - {next_state,CurrentState,NewData,Actions}. +

+ 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 + {next_state,CurrentState,NewData,Actions}. +

keep_state_and_data - The gen_statem will keep the current state or - do a state transition to the current state if you like, - keep the current server data, - and execute all Actions. - This is the same as - {next_state,CurrentState,CurrentData,Actions}. +

+ 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}. +

All these terms are tuples or atoms and this property - will hold in any future version of gen_statem, - just in case you need such a promise. + will hold in any future version of gen_statem.

- - - - - Create a linked gen_statem process - -

- Creates a gen_statem process according - to OTP design principles - (using - proc_lib - primitives) - that is linked to the calling process. - This is essential when the gen_statem shall be part of - a supervision tree so it gets linked to its supervisor. -

-

- The gen_statem process calls - Module:init/1 - to initialize the server. To ensure a synchronized start-up - procedure, start_link/3,4 does not return until - Module:init/1 - has returned. -

-

- ServerName specifies the - - server_name() - - to register for the gen_statem. - If the gen_statem is started with start_link/3 - no ServerName is provided and - the gen_statem is not registered. -

-

Module is the name of the callback module.

-

- Args is an arbitrary term which is passed as - the argument to - Module:init/1. -

-

- If the option {timeout,Time} is present in - Opts, the gen_statem - is allowed to spend Time milliseconds initializing - or it will be terminated and the start function will return - {error,timeout}. -

-

- If the option - {debug,Dbgs} - is present in Opts, debugging through - sys is activated. -

-

- If the option {spawn_opt,SpawnOpts} is present in - Opts, SpawnOpts will be passed - as option list to - spawn_opt/2 - which is used to spawn the gen_statem process. -

- -

- Using the spawn option monitor is currently not - allowed, but will cause this function to fail with reason - badarg. -

-
-

- If the gen_statem is successfully created - and initialized this function returns - - {ok,Pid}, - - where Pid is the pid() - of the gen_statem. - If there already exists a process with the specified - ServerName this function returns - {error,{already_started,Pid}}, - where Pid is the pid() of that process. -

-

- If Module:init/1 fails with Reason, - this function returns - {error,Reason}. - If Module:init/1 returns - - {stop,Reason} - - or - ignore, - the process is terminated and this function - returns - - {error,Reason} - - or - ignore, - respectively. -

-
-
- - - - - - Create a stand-alone gen_statem process - -

- Creates a stand-alone gen_statem process according to - OTP design principles (using - proc_lib - primitives). - Since it does not get linked to the calling process - this start function can not be used by a supervisor - to start a child. -

-

- See start_link/3,4 - for a description of arguments and return values. -

-
-
- - - - Synchronously stop a generic server - -

- The same as - - stop(ServerRef, normal, infinity). - -

-
-
- - - Synchronously stop a generic server - -

- Orders the gen_statem - - ServerRef - - to exit with the given Reason - and waits for it to terminate. - The gen_statem will call - - Module:terminate/3 - - before exiting. -

-

- This function returns ok if the server terminates - with the expected reason. Any other reason than normal, - shutdown, or {shutdown,Term} will cause an - error report to be issued through - - error_logger:format/2. - - The default Reason is normal. -

-

- Timeout is an integer greater than zero - which specifies how many milliseconds to wait for the server to - terminate, or the atom infinity to wait indefinitely. - The default value is infinity. - If the server has not terminated within the specified time, - a timeout exception is raised. -

-

- If the process does not exist, a noproc exception - is raised. -

-
-
- - - - Make a synchronous call to a gen_statem + + + Make a synchronous call to a gen_statem.

Makes a synchronous call to the gen_statem @@ -1093,7 +970,7 @@ handle_event(_, _, State, Data) -> by sending a request and waiting until its reply arrives. - The gen_statem will call the + The gen_statem calls the state function with event_type() {call,From} and event content @@ -1108,33 +985,33 @@ handle_event(_, _, State, Data) -> and that Reply becomes the return value of this function.

-

- Timeout is an integer greater than zero +

+ Timeout is an integer > 0, which specifies how many milliseconds to wait for a reply, or the atom infinity to wait indefinitely, - which is the default. If no reply is received within + which is the default. If no reply is received within the specified time, the function call fails.

To avoid getting a late reply in the caller's - inbox this function spawns a proxy process that - does the call. A late reply gets delivered to the - dead proxy process hence gets discarded. This is + inbox, this function spawns a proxy process that + does the call. A late reply gets delivered to the + dead proxy process, hence gets discarded. This is less efficient than using Timeout =:= infinity.

-

- The call may fail for example if the gen_statem dies +

+ The call can fail, for example, if the gen_statem dies before or during this function call.

- - Send an asynchronous event to a gen_statem + + Send an asynchronous event to a gen_statem.

Sends an asynchronous event to the gen_statem @@ -1144,7 +1021,7 @@ handle_event(_, _, State, Data) -> and returns ok immediately, ignoring if the destination node or gen_statem does not exist. - The gen_statem will call the + The gen_statem calls the state function with event_type() cast and event content @@ -1154,44 +1031,8 @@ handle_event(_, _, State, Data) -> - - - Reply to a caller - -

- This function can be used by a gen_statem - to explicitly send a reply to a process that waits in - call/2 - when the reply cannot be defined in - the return value of a - state function. -

-

- From must be the term from the - - {call,From} - - argument 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 sent with this function will not be visible - in sys debug output. -

-
-
-
- - - - Enter the gen_statem receive loop + + Enter the gen_statem receive loop.

The same as @@ -1204,12 +1045,13 @@ handle_event(_, _, State, Data) ->

+ - - Enter the gen_statem receive loop + + Enter the gen_statem receive loop.

- If Server_or_Actions is a list() + If Server_or_Actions is a list(), the same as enter_loop/7 except that no @@ -1228,34 +1070,35 @@ handle_event(_, _, State, Data) ->

+ - - Enter the gen_statem receive loop + + Enter the gen_statem receive loop. -

- Makes an the calling process become a gen_statem. - Does not return, instead the calling process will enter - the gen_statem receive loop and become +

+ Makes the calling process become a gen_statem. + Does not return, instead the calling process enters + the gen_statem receive loop and becomes a gen_statem server. The process must have been started using one of the start functions in - proc_lib. + proc_lib. The user is responsible for any initialization of the process, including registering a name for it.

-

+

This function is useful when a more complex initialization - procedure is needed than - the gen_statem behaviour provides. + procedure is needed than + the gen_statem behavior provides.

-

- Module, Opts and +

+ Module, Opts, and Server have the same meanings as when calling - - gen_statem:start[_link]/3,4. - - However, the + + start[_link]/3,4 + . + However, the server_name() @@ -1263,265 +1106,260 @@ handle_event(_, _, State, Data) -> before this function is called.

CallbackMode, State, - Data and Actions + Data, and Actions have the same meanings as in the return value of - Module:init/1. - Also, the callback module Module + Module:init/1. + Also, the callback module Module does not need to export an init/1 function.

- Failure: If the calling process was not started by a - proc_lib + The function fails if the calling process was not started by a + proc_lib start function, or if it is not registered - according to + according to server_name().

-
- - - -
- CALLBACK FUNCTIONS -

- The following functions should be exported from a - gen_statem callback module. -

-
- - - Module:init(Args) -> Result - Initialize process and internal state - - Args = term() - Result = {CallbackMode,State,Data} -  | {CallbackMode,State,Data,Actions} -  | {stop,Reason} | ignore - - CallbackMode = - callback_mode() - - State = state() - - Data = data() - - - Actions = - [action()] | - action() - - Reason = term() - + + + Reply to a caller. -

- Whenever a gen_statem is started using - start_link/3,4 - or - start/3,4, - this function is called by the new process to initialize - the implementation state and server data. -

-

- Args is the Args argument provided to the start - function. -

-

- If the initialization is successful, the function should - return {CallbackMode,State,Data} or - {CallbackMode,State,Data,Actions}. - CallbackMode selects the - callback mode. - of the gen_statem. - State is the initial - state() - and Data the initial server - data(). + This function can be used by a gen_statem + to explicitly send a reply to a process that waits in + call/2 + when the reply cannot be defined in + the return value of a + state function.

- The Actions - are executed when entering the first - state just as for a + From must be the term from argument + + {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 sent with this function is not visible + in sys debug output. +

+
+
+
+ + + + + Create a standalone gen_statem process. +

- If something goes wrong during the initialization - the function should return {stop,Reason} - or ignore. See - start_link/3,4. + Creates a standalone gen_statem process according to + OTP design principles (using + proc_lib + primitives). + As it does not get linked to the calling process, + this start function cannot be used by a supervisor + to start a child.

- This function may use - throw/1 - to return Result. + For a description of arguments and return values, see + start_link/3,4.

- Module:StateName(EventType, EventContent, Data) -> - StateFunctionResult - - Module:handle_event(EventType, EventContent, - State, Data) -> HandleEventResult - - Handle an event - - - EventType = - event_type() - - EventContent = term() - - State = - state() - - - Data = NewData = - data() - - - StateFunctionResult = - - state_function_result() - - - - HandleEventResult = - - handle_event_result() - - - + + + Create a linked gen_statem process.

- Whenever a gen_statem receives an event from - call/2, - cast/2 or - as a normal process message one of these functions is called. If - callback mode - is state_functions then Module:StateName/3 is called, - and if it is handle_event_function - then Module:handle_event/4 is called. + Creates a gen_statem process according + to OTP design principles + (using + proc_lib + primitives) + that is linked to the calling process. + This is essential when the gen_statem must be part of + a supervision tree so it gets linked to its supervisor.

- If EventType is - {call,From} - the caller is waiting for a reply. The reply can be sent - from this or from any other - state function - by returning with {reply,From,Reply} in - Actions, in - Replies - or by calling - reply(From, Reply). + The gen_statem process calls + Module:init/1 + to initialize the server. To ensure a synchronized startup + procedure, start_link/3,4 does not return until + Module:init/1 + has returned.

- If this function returns with a next state that - does not match equal (=/=) to the current state - all postponed events will be retried in the next state. + ServerName specifies the + + server_name() + + to register for the gen_statem. + If the gen_statem is started with start_link/3, + no ServerName is provided and + the gen_statem is not registered.

-

- The only difference between StateFunctionResult and - HandleEventResult is that for StateFunctionResult - the next state has to be an atom but for HandleEventResult - there is no restriction on the next state. +

Module is the name of the callback module.

+

+ Args is an arbitrary term that is passed as + the argument to + Module:init/1.

+ + +

+ If option {timeout,Time} is present in + Opts, the gen_statem + is allowed to spend Time milliseconds initializing + or it terminates and the start function returns + + {error,timeout}. +

+
+ +

+ If option + {debug,Dbgs} + is present in Opts, debugging through + sys is activated. +

+
+ +

+ If option {spawn_opt,SpawnOpts} is present in + Opts, SpawnOpts is passed + as option list to + erlang:spawn_opt/2, + which is used to spawn the gen_statem process. +

+
+
+ +

+ Using spawn option monitor is not + allowed, it cause this function to fail with reason + badarg. +

+

- See action() - for options that can be set and actions that can be done - by gen_statem after returning from this function. + If the gen_statem is successfully created + and initialized, this function returns + + {ok,Pid} + , + where Pid is the pid() + of the gen_statem. + If a process with the specified ServerName + exists already, this function returns + + {error,{already_started,Pid}}, + where Pid is the pid() of that process.

- These functions may use - throw/1, - to return the result. + If Module:init/1 fails with Reason, + this function returns + {error,Reason}. + If Module:init/1 returns + + {stop,Reason} + + or + ignore, + the process is terminated and this function + returns + + {error,Reason} + + or + ignore, + respectively.

- Module:terminate(Reason, State, Data) -> Ignored - Clean up before termination - - Reason = normal | shutdown | {shutdown,term()} | term() - State = state() - Data = data() - Ignored = term() - + + Synchronously stop a generic server. -

- This function is called by a gen_statem - when it is about to terminate. It should be the opposite of - Module:init/1 - and do any necessary cleaning up. When it returns, - the gen_statem terminates with Reason. The return - value is ignored.

-

- Reason is a term denoting the stop reason and - State - is the internal state of the gen_statem. -

-

- Reason depends on why the gen_statem - is terminating. - If it is because another callback function has returned a - stop tuple {stop,Reason} in - Actions, - Reason will have the value specified in that tuple. - If it is due to a failure, Reason is the error reason. +

+ The same as + + stop(ServerRef, normal, infinity). +

-

- If the gen_statem is part of a supervision tree and is - ordered by its supervisor to terminate, this function will be - called with Reason = shutdown if the following - conditions apply:

- - - the gen_statem has been set - to trap exit signals, and - - - the shutdown strategy as defined in the supervisor's - child specification is an integer timeout value, not - brutal_kill. - - -

- Even if the gen_statem is not - part of a supervision tree, this function will be called - if it receives an 'EXIT' message from its parent. - Reason will be the same as - in the 'EXIT' message. + + + + + + Synchronously stop a generic server. + +

+ Orders the gen_statem + + ServerRef + + to exit with the specified Reason + and waits for it to terminate. + The gen_statem calls + + Module:terminate/3 + + before exiting.

-

- Otherwise, the gen_statem will be immediately terminated. +

+ This function returns ok if the server terminates + with the expected reason. Any other reason than normal, + shutdown, or {shutdown,Term} causes an + error report to be issued through + + error_logger:format/2 + . + The default Reason is normal.

-

- Note that for any other reason than normal, - shutdown, or {shutdown,Term} - the gen_statem is assumed to terminate due to an error - and an error report is issued using - - error_logger:format/2. - +

+ Timeout is an integer > 0, + which specifies how many milliseconds to wait for the server to + terminate, or the atom infinity to wait indefinitely. + Defaults to infinity. + If the server does not terminate within the specified time, + a timeout exception is raised.

- This function may use - throw/1 - to return Ignored, which is ignored anyway. + If the process does not exist, a noproc exception + is raised.

+
+ +
+ Callback Functions +

+ The following functions are to be exported from a + gen_statem callback module. +

+
+ Module:code_change(OldVsn, OldState, OldData, Extra) -> Result - Update the internal state during upgrade/downgrade + Update the internal state during upgrade/downgrade. OldVsn = Vsn | {down,Vsn}   Vsn = term() @@ -1544,24 +1382,23 @@ handle_event(_, _, State, Data) ->

- This function is called by a gen_statem when it should - update its internal state during a release upgrade/downgrade, - that is when the instruction {update,Module,Change,...} - where Change={advanced,Extra} is given in the + 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 appup - file. See - + file. For more information, see + OTP Design Principles - - for more information. + .

-

- In the case of an upgrade, OldVsn is Vsn, and - in the case of a downgrade, OldVsn is - {down,Vsn}. Vsn is defined by the vsn - attribute(s) of the old version of the callback module - Module. If no such attribute is defined, the version - is the checksum of the BEAM file. +

+ For an upgrade, OldVsn is Vsn, and + for a downgrade, OldVsn is + {down,Vsn}. Vsn is defined by the vsn + attribute(s) of the old version of the callback module + Module. If no such attribute is defined, the version + is the checksum of the Beam file.

@@ -1569,14 +1406,14 @@ handle_event(_, _, State, Data) -> callback mode - during release upgrade/downgrade, the upgrade is no problem - since the new code surely knows what callback mode - it needs, but for a downgrade this function will have to - know from the Extra argument that comes from the - appup + during release upgrade/downgrade, the upgrade is no problem, + as the new code surely knows what callback mode + it needs. However, for a downgrade this function must + know from argument Extra that comes from the + sasl:appup file what callback mode the old code did use. - It may also be possible to figure this out - from the {down,Vsn} argument since Vsn + It can also be possible to figure this out + from argument {down,Vsn}, as Vsn in effect defines the old callback module version.

@@ -1584,32 +1421,102 @@ handle_event(_, _, State, Data) -> OldState and OldData is the internal state of the gen_statem.

-

- Extra is passed as-is from the {advanced,Extra} - part of the update instruction. +

+ Extra is passed "as is" from the {advanced,Extra} + part of the update instruction.

-

- If successful, the function shall return the updated - internal state in an +

+ If successful, the function must return the updated + internal state in an {NewCallbackMode,NewState,NewData} tuple.

If the function returns Reason, the ongoing - upgrade will fail and roll back to the old release.

+ upgrade fails and rolls back to the old release.

- This function may use - throw/1 + This function can use + erlang:throw/1 to return Result or Reason.

+ + Module:init(Args) -> Result + Initialize process and internal state. + + Args = term() + Result = {CallbackMode,State,Data} +  | {CallbackMode,State,Data,Actions} +  | {stop,Reason} | ignore + + CallbackMode = + callback_mode() + + State = state() + + Data = data() + + + Actions = + [action()] | + action() + + Reason = term() + + + +

+ Whenever a gen_statem is started using + start_link/3,4 + or + start/3,4, + this function is called by the new process to initialize + the implementation state and server data. +

+

+ Args is the Args argument provided to the start + function. +

+

+ If the initialization is successful, the function is to + return {CallbackMode,State,Data} or + {CallbackMode,State,Data,Actions}. + CallbackMode selects the + + callback mode + of the gen_statem. + State is the initial + state() + and Data the initial server + data(). +

+

+ The Actions + are executed when entering the first + state just as for a + state function. +

+

+ If the initialization fails, + the function is to return {stop,Reason} + or ignore; see + start_link/3,4. +

+

+ This function can use + erlang:throw/1 + to return Result. +

+
+
+ Module:format_status(Opt, [PDict,State,Data]) -> Status Optional function for providing a term describing the - current gen_statem status + current gen_statem status. Opt = normal | terminate PDict = [{Key, Value}] @@ -1627,58 +1534,59 @@ handle_event(_, _, State, Data) -> -

- This callback is optional, so a callback module need not - export it. The gen_statem module provides a default - implementation of this function that returns - {State,Data}. If this callback fails the default - function will return {State,Info} +

+ This callback is optional, so a callback module does not need + to export it. The gen_statem module provides a default + implementation of this function that returns + {State,Data}. If this callback fails, the default + function returns {State,Info}, where Info informs of the crash but no details, to hide possibly sensitive data.

-

This function is called by a gen_statem process when:

+

This function is called by a gen_statem process when + any of the following apply:

- + One of - + sys:get_status/1,2 - is invoked to get the gen_statem status. Opt is set - to the atom normal for this case. + is invoked to get the gen_statem status. Opt is set + to the atom normal for this case. - + The gen_statem terminates abnormally and logs an error. Opt is set to the atom terminate for this case. - +

- This function is useful for customising the form and + This function is useful for changing the form and appearance of the gen_statem status for these cases. A - callback module wishing to customise the + callback module wishing to change the sys:get_status/1,2 - return value as well as how + return value and how its status appears in termination error logs exports an - instance of format_status/2 that returns a term + instance of format_status/2, which returns a term describing the current status of the gen_statem.

-

- PDict is the current value of the gen_statem's - process dictionary. +

+ PDict is the current value of the process dictionary + of the gen_statem.

-

+

State is the internal state of the gen_statem.

-

+

Data is the internal server data of the gen_statem.

-

- The function should return Status, a term that - customises the details of the current state and status of +

+ The function is to return Status, a term that + changes the details of the current state and status of the gen_statem. There are no restrictions on the form Status can take, but for the @@ -1687,38 +1595,197 @@ handle_event(_, _, State, Data) -> case (when Opt is normal), the recommended form for the Status value is [{data, [{"State", - Term}]}] where Term provides relevant details of - the gen_statem state. Following this recommendation isn't - required, but doing so will make the callback module status + Term}]}], where Term provides relevant details of + the gen_statem state. Following this recommendation is not + required, but it makes the callback module status consistent with the rest of the sys:get_status/1,2 return value.

-

+

One use for this function is to return compact alternative state representations to avoid having large state terms - printed in logfiles. Another is to hide sensitive data from + printed in log files. Another use is to hide sensitive data from being written to the error log.

- This function may use - throw/1 + This function can use + erlang:throw/1 to return Status.

+ + Module:StateName(EventType, EventContent, Data) -> + StateFunctionResult + + Module:handle_event(EventType, EventContent, + State, Data) -> HandleEventResult + + Handle an event. + + + EventType = + event_type() + + EventContent = term() + + State = + state() + + + Data = NewData = + data() + + + StateFunctionResult = + + state_function_result() + + + + HandleEventResult = + + handle_event_result() + + + + +

+ Whenever a gen_statem receives an event from + call/2, + cast/2, or + as a normal process message, one of these functions is called. If + callback mode + is state_functions, Module:StateName/3 is called, + and if it is handle_event_function, + Module:handle_event/4 is called. +

+

+ If EventType is + {call,From}, + the caller waits for a reply. The reply can be sent + from this or from any other + state function + by returning with {reply,From,Reply} in + Actions, in + Replies, + or by calling + reply(From, Reply). +

+

+ If this function returns with a next state that + does not match equal (=/=) to the current state, + all postponed events are retried in the next state. +

+

+ The only difference between StateFunctionResult and + HandleEventResult is that for StateFunctionResult + the next state must be an atom, but for HandleEventResult + there is no restriction on the next state. +

+

+ For options that can be set and actions that can be done + by gen_statem after returning from this function, + see action(). +

+

+ These functions can use + erlang:throw/1, + to return the result. +

+
+
+ + + Module:terminate(Reason, State, Data) -> Ignored + Clean up before termination. + + Reason = normal | shutdown | {shutdown,term()} | term() + State = state() + Data = data() + Ignored = term() + + +

+ This function is called by a gen_statem + when it is about to terminate. It is to be the opposite of + Module:init/1 + and do any necessary cleaning up. When it returns, + the gen_statem terminates with Reason. The return + value is ignored.

+

+ Reason is a term denoting the stop reason and + State + is the internal state of the gen_statem. +

+

+ Reason depends on why the gen_statem + is terminating. + If it is because another callback function has returned, a + stop tuple {stop,Reason} in + Actions, + Reason has the value specified in that tuple. + If it is because of a failure, Reason is the error reason. +

+

+ If the gen_statem is part of a supervision tree and is + ordered by its supervisor to terminate, this function is + called with Reason = shutdown if both the following + conditions apply:

+ + +

+ The gen_statem has been set + to trap exit signals. +

+
+ +

+ The shutdown strategy as defined in the supervisor's + child specification is an integer time-out value, not + brutal_kill. +

+
+
+

+ Even if the gen_statem is not + part of a supervision tree, this function is called + if it receives an 'EXIT' message from its parent. + Reason is the same as + in the 'EXIT' message. +

+

+ Otherwise, the gen_statem is immediately terminated. +

+

+ Notice that for any other reason than normal, + shutdown, or {shutdown,Term}, + the gen_statem is assumed to terminate because of an error + and an error report is issued using + + error_logger:format/2. + +

+

+ This function can use + erlang:throw/1 + to return Ignored, which is ignored anyway. +

+
+
- SEE ALSO + See Also

gen_event(3), gen_fsm(3), gen_server(3), - supervisor(3), proc_lib(3), + supervisor(3), sys(3)

-- cgit v1.2.3