diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/stdlib/doc/src/gen_statem.xml | 1769 |
1 files changed, 858 insertions, 911 deletions
diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index d83e17b177..b1d9799917 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -29,39 +29,49 @@ <rev></rev> </header> <module>gen_statem</module> - <modulesummary>Generic State Machine Behaviour</modulesummary> + <modulesummary>Generic state machine behavior.</modulesummary> <description> <p> - A behaviour module for implementing a state machine. Two + This behavior module provides a state machine. Two <seealso marker="#type-callback_mode"><em>callback modes</em></seealso> - are supported. One for finite state machines - (<seealso marker="gen_fsm"><c>gen_fsm</c></seealso> 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. - </p> - <p> - 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: </p> + <list type="bulleted"> + <item> + <p>One for finite-state machines + (<seealso marker="gen_fsm"><c>gen_fsm</c></seealso> like), + which requires the state to be an atom and uses that state as + the name of the current callback function + </p> + </item> + <item> + <p>One without restriction on the state data type + that uses one callback function for all states + </p> + </item> + </list> + <note> + <p> + This is a new behavior in Erlang/OTP 19.0. + It has been thoroughly reviewed, is stable enough + to be used by at least two heavy OTP applications, and is here to stay. + 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. + </p> + </note> <p> - The <c>gen_statem</c> behaviour is intended to replace + The <c>gen_statem</c> behavior is intended to replace <seealso marker="gen_fsm"><c>gen_fsm</c></seealso> for new code. - It has the same features and add some really useful: + It has the same features and adds some really useful: </p> <list type="bulleted"> - <item>State code is gathered</item> - <item>The state can be any term</item> - <item>Events can be postponed</item> - <item>Events can be self generated</item> - <item>A reply can be sent from a later state</item> - <item>There can be multiple sys traceable replies</item> + <item>State code is gathered.</item> + <item>The state can be any term.</item> + <item>Events can be postponed.</item> + <item>Events can be self-generated.</item> + <item>A reply can be sent from a later state.</item> + <item>There can be multiple <c>sys</c> traceable replies.</item> </list> <p> The callback model(s) for <c>gen_statem</c> differs from @@ -71,19 +81,16 @@ </p> <p> A generic state machine process (<c>gen_statem</c>) 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 - <seealso marker="doc/design_principles:statem"> - OTP Design Principles - </seealso> - for more information. + 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 + <seealso marker="doc/design_principles:statem">OTP Design Principles</seealso>. </p> <p> A <c>gen_statem</c> 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:</p> + callback module exporting a predefined set of functions. + The relationship between the behavior functions and the callback + functions is as follows:</p> <pre> gen_statem module Callback module ----------------- --------------- @@ -103,59 +110,54 @@ erlang:'!' -----> Module:StateName/3 - -----> Module:code_change/4</pre> <p> Events are of different - <seealso marker="#type-event_type">types</seealso> + <seealso marker="#type-event_type">types</seealso>, so the callback functions can know the origin of an event and how to respond. </p> <p> If a callback function fails or returns a bad value, - the <c>gen_statem</c> will terminate. An exception of class - <seealso marker="erts:erlang#throw/1"><c>throw</c></seealso>, - however, is not regarded as an error but as a valid return. + the <c>gen_statem</c> terminates. However, an exception of class + <seealso marker="erts:erlang#throw/1"><c>throw</c></seealso> + is not regarded as an error but as a valid return. </p> - <marker id="state_function" /> + <marker id="state_function"/> <p> The "<em>state function</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, and is selected depending on which + for all events in this state. It is selected depending on which <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> - that the implementation specifies when the the server starts. + that the implementation specifies when the server starts. </p> <p> When the <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> - is <c>state_functions</c>, the state has to be an atom and - is used as the state function name. See - <seealso marker="#Module:StateName/3"> - <c>Module:StateName/3</c> - </seealso>. + is <c>state_functions</c>, the state must be an atom and + is used as the state function name; see + <seealso marker="#Module:StateName/3"><c>Module:StateName/3</c></seealso>. 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 - <seealso marker="#Module:terminate/3"> - <c>Module:terminate/3</c> - </seealso> makes the state name <c>terminate</c> unusable. + Notice that in this mode + the mandatory callback function + <seealso marker="#Module:terminate/3"><c>Module:terminate/3</c></seealso> + makes the state name <c>terminate</c> unusable. </p> <p> When the <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> - is <c>handle_event_function</c> the state can be any term + is <c>handle_event_function</c>, the state can be any term and the state function name is - <seealso marker="#Module:handle_event/4"> - <c>Module:handle_event/4</c> - </seealso>. + <seealso marker="#Module:handle_event/4"><c>Module:handle_event/4</c></seealso>. 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 an event 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_function">state function</seealso> - 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. </p> @@ -163,91 +165,85 @@ erlang:'!' -----> Module:StateName/3 The <c>gen_statem</c> 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. </p> <p> The <seealso marker="#state_function">state function</seealso> can insert events using the - <seealso marker="#type-action"> - <c>action()</c> <c>next_event</c> - </seealso> + <seealso marker="#type-action"><c>action()</c></seealso> + <c>next_event</c> 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 - <seealso marker="#type-event_type"> - <c>event_type()</c> - </seealso> - <c>internal</c> that can be used for such events making them impossible + to the state function. 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. </p> <p> Inserting an event replaces the trick of calling your own state handling functions that you often would have to - resort to in for example <seealso marker="gen_fsm"><c>gen_fsm</c></seealso> + resort to in, for example, + <seealso marker="gen_fsm"><c>gen_fsm</c></seealso> to force processing an inserted event before others. - A warning, though: if you in <c>gen_statem</c> 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. </p> + <note> + <p>If you in <c>gen_statem</c>, 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. + </p> + </note> <p> - See the type - <seealso marker="#type-transition_option"> - <c>transition_option()</c> - </seealso> - for the details of a state transition. + For the details of a state transition, see type + <seealso marker="#type-transition_option"><c>transition_option()</c></seealso>. </p> <p> - A <c>gen_statem</c> handles system messages as documented in + A <c>gen_statem</c> handles system messages as described in <seealso marker="sys"><c>sys</c></seealso>. - The <c>sys</c>module can be used for debugging a <c>gen_statem</c>. + The <c>sys</c> module can be used for debugging a <c>gen_statem</c>. </p> <p> - Note that a <c>gen_statem</c> does not trap exit signals + Notice that a <c>gen_statem</c> does not trap exit signals automatically, this must be explicitly initiated in the callback module (by calling - <seealso marker="erts:erlang#process_flag/2"> - <c>process_flag(trap_exit, true)</c></seealso>. + <seealso marker="erts:erlang#process_flag/2"><c>process_flag(trap_exit, true)</c></seealso>. </p> <p> Unless otherwise stated, all functions in this module fail if the specified <c>gen_statem</c> does not exist or - if bad arguments are given. + if bad arguments are specified. </p> <p> The <c>gen_statem</c> process can go into hibernation; see - <seealso marker="proc_lib#hibernate/3"> - <c>proc_lib:hibernate/3</c>. - </seealso> + <seealso marker="proc_lib#hibernate/3"><c>proc_lib:hibernate/3</c></seealso>. It is done when a <seealso marker="#state_function">state function</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> - 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 - <seealso marker="erts:erlang#hibernate/3"> - <c>erlang:hibernate/3</c>. - </seealso> + <seealso marker="erts:erlang#hibernate/3"><c>erlang:hibernate/3</c></seealso>. </p> </description> <section> - <title>EXAMPLE</title> + <title>Example</title> <p> - This example shows a simple pushbutton model + The following example shows a simple pushbutton model for a toggling pushbutton implemented with <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> <c>state_functions</c>. You can push the button and it replies if it went on or off, and you can ask for a count of how many times it has been - pushed to on. + pushed to switch on. </p> - <p>This is the complete callback module file <c>pushbutton.erl</c>:</p> + <p>The following is the complete callback module file + <c>pushbutton.erl</c>:</p> <code type="erl"> -module(pushbutton). -behaviour(gen_statem). @@ -305,7 +301,7 @@ handle_event(_, _, Data) -> %% Ignore all other events {keep_state,Data}. </code> - <p>And this is a shell session when running it:</p> + <p>The following is a shell session when running it:</p> <pre> 1> pushbutton:start(). {ok,<0.36.0>} @@ -326,12 +322,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) </pre> - <p> - And just to compare styles here is the same example using + To compare styles, here follows the same example using <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> - <c>state_functions</c>, or rather here is code to replace - from the <c>init/1</c> function of the <c>pushbutton.erl</c> + <c>state_functions</c>, or rather the code to replace + from function <c>init/1</c> of the <c>pushbutton.erl</c> example file above: </p> <code type="erl"> @@ -364,107 +359,108 @@ handle_event(_, _, State, Data) -> <datatypes> <datatype> - <name name="server_name" /> + <name name="server_name"/> <desc> <p> Name specification to use when starting - a <c>gen_statem</c> server. See - <seealso marker="#start_link/3"> - <c>start_link/3</c> - </seealso> + a <c>gen_statem</c> server. See + <seealso marker="#start_link/3"><c>start_link/3</c></seealso> and - <seealso marker="#type-server_ref"> - <c>server_ref()</c> - </seealso> below. + <seealso marker="#type-server_ref"><c>server_ref()</c></seealso> + below. </p> </desc> </datatype> <datatype> - <name name="server_ref" /> + <name name="server_ref"/> <desc> <p> Server specification to use when addressing a <c>gen_statem</c> server. See <seealso marker="#call/2"><c>call/2</c></seealso> and - <seealso marker="#type-server_name"> - <c>server_name()</c> - </seealso> + <seealso marker="#type-server_name"><c>server_name()</c></seealso> above. </p> <p>It can be:</p> <taglist> - <tag><c>pid()</c><br /> - <c>LocalName</c></tag> - <item>The <c>gen_statem</c> is locally registered.</item> + <tag><c>pid() | LocalName</c></tag> + <item> + <p> + The <c>gen_statem</c> is locally registered. + </p> + </item> <tag><c>{Name,Node}</c></tag> <item> - The <c>gen_statem</c> is locally registered - on another node. + <p> + The <c>gen_statem</c> is locally registered + on another node. + </p> </item> <tag><c>{global,GlobalName}</c></tag> <item> - The <c>gen_statem</c> is globally registered - in <seealso marker="kernel:global"><c>global</c></seealso>. + <p> + The <c>gen_statem</c> is globally registered in + <seealso marker="kernel:global"><c>kernel:global</c></seealso>. + </p> </item> <tag><c>{via,RegMod,ViaName}</c></tag> <item> - The <c>gen_statem</c> is registered through - an alternative process registry. - The registry callback module <c>RegMod</c> - should export the functions - <c>register_name/2</c>, <c>unregister_name/1</c>, - <c>whereis_name/1</c> and <c>send/2</c>, - which should behave like the corresponding functions - in <seealso marker="kernel:global"><c>global</c></seealso>. - Thus, <c>{via,global,GlobalName}</c> is the same as - <c>{global,GlobalName}</c>. + <p> + The <c>gen_statem</c> is registered in + an alternative process registry. + The registry callback module <c>RegMod</c> + is to export functions + <c>register_name/2</c>, <c>unregister_name/1</c>, + <c>whereis_name/1</c>, and <c>send/2</c>, + which are to behave like the corresponding functions in + <seealso marker="kernel:global"><c>kernel:global</c></seealso>. + Thus, <c>{via,global,GlobalName}</c> is the same as + <c>{global,GlobalName}</c>. + </p> </item> </taglist> </desc> </datatype> <datatype> - <name name="debug_opt" /> + <name name="debug_opt"/> <desc> <p> Debug option that can be used when starting - a <c>gen_statem</c> server through for example + a <c>gen_statem</c> server through, for example, <seealso marker="#enter_loop/5"><c>enter_loop/5</c></seealso>. </p> <p> - For every entry in <c><anno>Dbgs</anno></c> + For every entry in <c><anno>Dbgs</anno></c>, the corresponding function in - <seealso marker="sys"><c>sys</c></seealso> will be called. + <seealso marker="sys"><c>sys</c></seealso> is called. </p> </desc> </datatype> <datatype> - <name name="start_opt" /> + <name name="start_opt"/> <desc> <p> Options that can be used when starting - a <c>gen_statem</c> server through for example + a <c>gen_statem</c> server through, for example, <seealso marker="#start_link/3"><c>start_link/3</c></seealso>. </p> </desc> </datatype> <datatype> - <name name="start_ret" /> + <name name="start_ret"/> <desc> <p> - Return value from the start functions for_example + Return value from the start functions, for example, <seealso marker="#start_link/3"><c>start_link/3</c></seealso>. </p> </desc> </datatype> - <datatype> - <name name="from" /> + <name name="from"/> <desc> <p> - Destination to use when replying through for example the - <seealso marker="#type-action"> - <c>action()</c> - </seealso> + Destination to use when replying through, for example, the + <seealso marker="#type-action"><c>action()</c></seealso> <c>{reply,From,Reply}</c> to a process that has called the <c>gen_statem</c> server using <seealso marker="#call/2"><c>call/2</c></seealso>. @@ -472,231 +468,228 @@ handle_event(_, _, State, Data) -> </desc> </datatype> <datatype> - <name name="state" /> + <name name="state"/> <desc> <p> - After a state change (<c>NextState =/= State</c>) + After a state change (<c>NextState =/= State</c>), all postponed events are retried. </p> </desc> </datatype> <datatype> - <name name="state_name" /> + <name name="state_name"/> <desc> <p> If the <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> is <c>state_functions</c>, - the state has to be of this type. + the state must be of this type. </p> </desc> </datatype> <datatype> - <name name="data" /> + <name name="data"/> <desc> <p> 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 <seealso marker="#type-state"><c>state()</c></seealso> 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. </p> </desc> </datatype> <datatype> - <name name="event_type" /> + <name name="event_type"/> <desc> <p> - External events are of 3 different type: - <c>{call,<anno>From</anno>}</c>, <c>cast</c> or <c>info</c>. + External events are of three types: + <c>{call,<anno>From</anno>}</c>, <c>cast</c>, or <c>info</c>. <seealso marker="#call/2">Calls</seealso> (synchronous) and <seealso marker="#cast/2">casts</seealso> 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 <c>info</c> originates from regular process messages sent - to the <c>gen_statem</c>. It is also possible for the state machine - implementation to generate events of types + to the <c>gen_statem</c>. Also, the state machine + implementation can generate events of types <c>timeout</c> and <c>internal</c> to itself. </p> </desc> </datatype> <datatype> - <name name="callback_mode" /> + <name name="callback_mode"/> <desc> <p> The <em>callback mode</em> is selected when starting the <c>gen_statem</c> using the return value from <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> or when calling - <seealso marker="#enter_loop/5"><c>enter_loop/5-7</c></seealso>, + <seealso marker="#enter_loop/5"><c>enter_loop/5,6,7</c></seealso>, and with the return value from - <seealso marker="#Module:code_change/4"> - <c>Module:code_change/4</c>. - </seealso> + <seealso marker="#Module:code_change/4"><c>Module:code_change/4</c></seealso>. </p> <taglist> <tag><c>state_functions</c></tag> <item> - The state has to be of type - <seealso marker="#type-state_name"><c>state_name()</c></seealso> - and one callback function per state that is - <seealso marker="#Module:StateName/3"> - <c>Module:StateName/3</c> - </seealso> - is used. + <p> + The state must be of type + <seealso marker="#type-state_name"><c>state_name()</c></seealso> + and one callback function per state, that is, + <seealso marker="#Module:StateName/3"><c>Module:StateName/3</c></seealso>, + is used. + </p> </item> <tag><c>handle_event_function</c></tag> <item> - The state can be any term and the callback function - <seealso marker="#Module:handle_event/4"> - <c>Module:handle_event/4</c> - </seealso> - is used for all states. + <p> + The state can be any term and the callback function + <seealso marker="#Module:handle_event/4"><c>Module:handle_event/4</c></seealso> + is used for all states. + </p> </item> </taglist> </desc> </datatype> <datatype> - <name name="transition_option" /> + <name name="transition_option"/> <desc> <p> - Transition options may be set by + Transition options can be set by <seealso marker="#type-action">actions</seealso> - and they modify some details below in how + and they modify the following in how the state transition is done: </p> <list type="ordered"> <item> - All - <seealso marker="#type-action">actions</seealso> - are processed in order of appearance. + <p> + All + <seealso marker="#type-action">actions</seealso> + are processed in order of appearance. + </p> </item> <item> - If - <seealso marker="#type-postpone"> - <c>postpone()</c> - </seealso> - is <c>true</c> - the current event is postponed. + <p> + If + <seealso marker="#type-postpone"><c>postpone()</c></seealso> + is <c>true</c>, + the current event is postponed. + </p> </item> <item> - If the state changes the queue of incoming events - is reset to start with the oldest postponed. + <p> + If the state changes, the queue of incoming events + is reset to start with the oldest postponed. + </p> </item> <item> - All events stored with - <seealso marker="#type-action"> - <c>action()</c> - </seealso> - <c>next_event</c> - are inserted in the queue to be processed before - all other events. + <p> + All events stored with + <seealso marker="#type-action"><c>action()</c></seealso> + <c>next_event</c> + are inserted in the queue to be processed before + all other events. + </p> </item> <item> - If an - <seealso marker="#type-event_timeout"> - <c>event_timeout()</c> - </seealso> - is set through - <seealso marker="#type-action"> - <c>action()</c> - </seealso> - <c>timeout</c> - an event timer may be started or a timeout zero event - may be enqueued. + <p> + If an + <seealso marker="#type-event_timeout"><c>event_timeout()</c></seealso> + is set through + <seealso marker="#type-action"><c>action()</c></seealso> + <c>timeout</c>, + an event timer can be started or a time-out zero event + can be enqueued. + </p> </item> <item> - The (possibly new) - <seealso marker="#state_function">state function</seealso> - is called with the oldest enqueued event if there is any, - otherwise the <c>gen_statem</c> goes into <c>receive</c> - or hibernation - (if - <seealso marker="#type-hibernate"> - <c>hibernate()</c> - </seealso> - is <c>true</c>) - to wait for the next message. In hibernation the next - non-system event awakens the <c>gen_statem</c>, or rather - the next incoming message awakens the <c>gen_statem</c> - but if it is a system event - it goes right back into hibernation. + <p> + The (possibly new) + <seealso marker="#state_function">state function</seealso> + is called with the oldest enqueued event if there is any, + otherwise the <c>gen_statem</c> goes into <c>receive</c> + or hibernation + (if + <seealso marker="#type-hibernate"><c>hibernate()</c></seealso> + is <c>true</c>) + to wait for the next message. In hibernation the next + non-system event awakens the <c>gen_statem</c>, or rather + the next incoming message awakens the <c>gen_statem</c>, + but if it is a system event + it goes right back into hibernation. + </p> </item> </list> </desc> </datatype> <datatype> - <name name="postpone" /> + <name name="postpone"/> <desc> <p> - If <c>true</c> postpone the current event and retry + If <c>true</c>, postpones the current event and retries it when the state changes (<c>NextState =/= State</c>). </p> </desc> </datatype> <datatype> - <name name="hibernate" /> + <name name="hibernate"/> <desc> <p> - If <c>true</c> hibernate the <c>gen_statem</c> + If <c>true</c>, hibernates the <c>gen_statem</c> by calling - <seealso marker="proc_lib#hibernate/3"> - <c>proc_lib:hibernate/3</c> - </seealso> + <seealso marker="proc_lib#hibernate/3"><c>proc_lib:hibernate/3</c></seealso> before going into <c>receive</c> to wait for a new external event. If there are enqueued events, - to prevent receiving any new event; a - <seealso marker="erts:erlang#garbage_collect/0"> - <c>garbage_collect/0</c> - </seealso> is done instead to simulate + to prevent receiving any new event, an + <seealso marker="erts:erlang#garbage_collect/0"><c>erlang:garbage_collect/0</c></seealso> + is done instead to simulate that the <c>gen_statem</c> entered hibernation and immediately got awakened by the oldest enqueued event. </p> </desc> </datatype> <datatype> - <name name="event_timeout" /> + <name name="event_timeout"/> <desc> <p> - Generate an event of + Generates an event of <seealso marker="#type-event_type"><c>event_type()</c></seealso> <c>timeout</c> - 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. </p> <p> - If the value is <c>infinity</c> no timer is started since - it will never trigger anyway. + If the value is <c>infinity</c>, no timer is started, as + it never triggers anyway. </p> <p> - If the value is <c>0</c> 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 <c>0</c> event - will be processed before any not yet received external event. + If the value is <c>0</c>, 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 <c>0</c> event + is processed before any not yet received external event. </p> <p> - 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. </p> </desc> </datatype> <datatype> - <name name="action" /> + <name name="action"/> <desc> <p> - These state transition actions may be invoked by + These state transition actions can be invoked by returning them from the - <seealso marker="#state_function">state function</seealso>, - from <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> + <seealso marker="#state_function">state function</seealso>, from + <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> or by giving them to <seealso marker="#enter_loop/6"><c>enter_loop/6,7</c></seealso>. </p> @@ -705,91 +698,81 @@ handle_event(_, _, State, Data) -> </p> <p> Actions that set - <seealso marker="#type-transition_option"> - transition options - </seealso> - overrides any previous of the same type, + <seealso marker="#type-transition_option">transition options</seealso> + override any previous of the same type, so the last in the containing list wins. - For example the last - <seealso marker="#type-event_timeout"> - <c>event_timeout()</c> - </seealso> + For example, the last + <seealso marker="#type-event_timeout"><c>event_timeout()</c></seealso> overrides any other <c>event_timeout()</c> in the list. </p> <taglist> <tag><c>postpone</c></tag> <item> - Set the - <seealso marker="#type-transition_option"> - <c>transition_option()</c> - </seealso> - <seealso marker="#type-postpone"> - <c>postpone()</c> - </seealso> - for this state transition. - This action is ignored when returned from - <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> - or given to - <seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso> - since there is no event to postpone in those cases. + <p> + Sets the + <seealso marker="#type-transition_option"><c>transition_option()</c></seealso> + <seealso marker="#type-postpone"><c>postpone()</c></seealso> + for this state transition. + This action is ignored when returned from + <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> + or given to + <seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso>, + as there is no event to postpone in those cases. + </p> </item> <tag><c>hibernate</c></tag> <item> - Set the - <seealso marker="#type-transition_option"> - <c>transition_option()</c> - </seealso> - <seealso marker="#type-hibernate"> - <c>hibernate()</c> - </seealso> - for this state transition. + <p> + Sets the + <seealso marker="#type-transition_option"><c>transition_option()</c></seealso> + <seealso marker="#type-hibernate"><c>hibernate()</c></seealso> + for this state transition. + </p> </item> <tag><c>Timeout</c></tag> <item> - Short for <c>{timeout,Timeout,Timeout}</c> that is - the timeout message is the timeout time. - This form exists to make the - <seealso marker="#state_function">state function</seealso> - return value <c>{next_state,NextState,NewData,Timeout}</c> - allowed like for - <seealso marker="gen_fsm#Module:StateName/2"> - <c>gen_fsm Module:StateName/2</c>. - </seealso> + <p> + Short for <c>{timeout,Timeout,Timeout}</c>, that is, + the time-out message is the time-out time. + This form exists to make the + <seealso marker="#state_function">state function</seealso> + return value <c>{next_state,NextState,NewData,Timeout}</c> + allowed like for <c>gen_fsm</c>'s + <seealso marker="gen_fsm#Module:StateName/2"><c>Module:StateName/2</c></seealso>. + </p> </item> <tag><c>timeout</c></tag> <item> - Set the - <seealso marker="#type-transition_option"> - <c>transition_option()</c> - </seealso> - <seealso marker="#type-event_timeout"> - <c>event_timeout()</c> - </seealso> - to <c><anno>Time</anno></c> with <c><anno>EventContent</anno></c>. + <p> + Sets the + <seealso marker="#type-transition_option"><c>transition_option()</c></seealso> + <seealso marker="#type-event_timeout"><c>event_timeout()</c></seealso> + to <c><anno>Time</anno></c> with <c><anno>EventContent</anno></c>. + </p> </item> <tag><c>reply_action()</c></tag> - <item>Reply to a caller.</item> + <item> + <p> + Replies to a caller. + </p> + </item> <tag><c>next_event</c></tag> <item> - Store the given <c><anno>EventType</anno></c> + <p> + Stores the specified <c><anno>EventType</anno></c> and <c><anno>EventContent</anno></c> for insertion after all actions have been executed. - </item> - <item> + </p> <p> The stored events are inserted in the queue as the next to process - before any already queued events. The order of these stored events - is preserved so the first <c>next_event</c> in the containing list - will become the first to process. + before any already queued events. The order of these stored events + is preserved, so the first <c>next_event</c> in the containing + list becomes the first to process. </p> - </item> - <item> <p> An event of type - <seealso marker="#type-event_type"> - <c>internal</c> - </seealso> - should be used when you want to reliably distinguish + <seealso marker="#type-event_type"><c>internal</c></seealso> + is to be used when you want to reliably distinguish an event inserted this way from any external event. </p> </item> @@ -797,303 +780,126 @@ handle_event(_, _, State, Data) -> </desc> </datatype> <datatype> - <name name="reply_action" /> + <name name="reply_action"/> <desc> <p> - Reply to a caller waiting for a reply in + Replies to a caller waiting for a reply in <seealso marker="#call/2"><c>call/2</c></seealso>. - <c><anno>From</anno></c> must be the term from the - <seealso marker="#type-event_type"> - <c>{call,<anno>From</anno>}</c> - </seealso> - argument to the + <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_function">state function</seealso>. </p> </desc> </datatype> <datatype> - <name name="state_function_result" /> + <name name="state_function_result"/> <desc> <taglist> <tag><c>next_state</c></tag> <item> - The <c>gen_statem</c> will do a state transition to - <c><anno>NextStateName</anno></c> - (which may be the same as the current state), - set <c><anno>NewData</anno></c> - and execute all <c><anno>Actions</anno></c> + <p> + The <c>gen_statem</c> does a state transition to + <c><anno>NextStateName</anno></c> + (which can be the same as the current state), + sets <c><anno>NewData</anno></c>, + and executes all <c><anno>Actions</anno></c>. + </p> </item> </taglist> <p> All these terms are tuples or atoms and this property - will hold in any future version of <c>gen_statem</c>, - just in case you need such a promise. + will hold in any future version of <c>gen_statem</c>. </p> </desc> </datatype> <datatype> - <name name="handle_event_result" /> + <name name="handle_event_result"/> <desc> <taglist> <tag><c>next_state</c></tag> <item> - The <c>gen_statem</c> will do a state transition to - <c><anno>NextState</anno></c> - (which may be the same as the current state), - set <c><anno>NewData</anno></c> - and execute all <c><anno>Actions</anno></c> + <p> + The <c>gen_statem</c> does a state transition to + <c><anno>NextState</anno></c> + (which can be the same as the current state), + sets <c><anno>NewData</anno></c>, + and executes all <c><anno>Actions</anno></c>. + </p> </item> </taglist> <p> All these terms are tuples or atoms and this property - will hold in any future version of <c>gen_statem</c>, - just in case you need such a promise. + will hold in any future version of <c>gen_statem</c>. </p> </desc> </datatype> <datatype> - <name name="common_state_callback_result" /> + <name name="common_state_callback_result"/> <desc> <taglist> <tag><c>stop</c></tag> <item> - Terminate the <c>gen_statem</c> by calling - <seealso marker="#Module:terminate/3"> - <c>Module:terminate/3</c> - </seealso> - with <c>Reason</c> and - <c><anno>NewData</anno></c>, if given. + <p> + Terminates the <c>gen_statem</c> by calling + <seealso marker="#Module:terminate/3"><c>Module:terminate/3</c></seealso> + with <c>Reason</c> and + <c><anno>NewData</anno></c>, if specified. + </p> </item> <tag><c>stop_and_reply</c></tag> <item> - Send all <c><anno>Replies</anno></c> - then terminate the <c>gen_statem</c> by calling - <seealso marker="#Module:terminate/3"> - <c>Module:terminate/3</c> - </seealso> - with <c>Reason</c> and - <c><anno>NewData</anno></c>, if given. + <p> + Sends all <c><anno>Replies</anno></c>, + then terminates the <c>gen_statem</c> by calling + <seealso marker="#Module:terminate/3"><c>Module:terminate/3</c></seealso> + with <c>Reason</c> and + <c><anno>NewData</anno></c>, if specified. + </p> </item> <tag><c>keep_state</c></tag> <item> - The <c>gen_statem</c> will keep the current state, or - do a state transition to the current state if you like, - set <c><anno>NewData</anno></c> - and execute all <c><anno>Actions</anno></c>. - This is the same as - <c>{next_state,CurrentState,<anno>NewData</anno>,<anno>Actions</anno>}</c>. + <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 + <c>{next_state,CurrentState,<anno>NewData</anno>,<anno>Actions</anno>}</c>. + </p> </item> <tag><c>keep_state_and_data</c></tag> <item> - The <c>gen_statem</c> 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 <c><anno>Actions</anno></c>. - This is the same as - <c>{next_state,CurrentState,CurrentData,<anno>Actions</anno>}</c>. + <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>. + </p> </item> </taglist> <p> All these terms are tuples or atoms and this property - will hold in any future version of <c>gen_statem</c>, - just in case you need such a promise. + will hold in any future version of <c>gen_statem</c>. </p> </desc> </datatype> </datatypes> <funcs> - - <func> - <name name="start_link" arity="3" /> - <name name="start_link" arity="4" /> - <fsummary>Create a linked <c>gen_statem</c> process</fsummary> - <desc> - <p> - Creates a <c>gen_statem</c> process according - to OTP design principles - (using - <seealso marker="proc_lib"><c>proc_lib</c></seealso> - primitives) - that is linked to the calling process. - This is essential when the <c>gen_statem</c> shall be part of - a supervision tree so it gets linked to its supervisor. - </p> - <p> - The <c>gen_statem</c> process calls - <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> - to initialize the server. To ensure a synchronized start-up - procedure, <c>start_link/3,4</c> does not return until - <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> - has returned. - </p> - <p> - <c><anno>ServerName</anno></c> specifies the - <seealso marker="#type-server_name"> - <c>server_name()</c> - </seealso> - to register for the <c>gen_statem</c>. - If the <c>gen_statem</c> is started with <c>start_link/3</c> - no <c><anno>ServerName</anno></c> is provided and - the <c>gen_statem</c> is not registered. - </p> - <p><c><anno>Module</anno></c> is the name of the callback module.</p> - <p> - <c><anno>Args</anno></c> is an arbitrary term which is passed as - the argument to - <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>. - </p> - <p> - If the option <c>{timeout,Time}</c> is present in - <c><anno>Opts</anno></c>, the <c>gen_statem</c> - is allowed to spend <c>Time</c> milliseconds initializing - or it will be terminated and the start function will return - <seealso marker="#type-start_ret"><c>{error,timeout}</c></seealso>. - </p> - <p> - If the option - <seealso marker="#type-debug_opt"><c>{debug,Dbgs}</c></seealso> - is present in <c><anno>Opts</anno></c>, debugging through - <seealso marker="sys"><c>sys</c></seealso> is activated. - </p> - <p> - If the option <c>{spawn_opt,SpawnOpts}</c> is present in - <c><anno>Opts</anno></c>, <c>SpawnOpts</c> will be passed - as option list to - <seealso marker="erts:erlang#spawn_opt/2"><c>spawn_opt/2</c></seealso> - which is used to spawn the <c>gen_statem</c> process. - </p> - <note> - <p> - Using the spawn option <c>monitor</c> is currently not - allowed, but will cause this function to fail with reason - <c>badarg</c>. - </p> - </note> - <p> - If the <c>gen_statem</c> is successfully created - and initialized this function returns - <seealso marker="#type-start_ret"> - <c>{ok,Pid}</c>, - </seealso> - where <c>Pid</c> is the <c>pid()</c> - of the <c>gen_statem</c>. - If there already exists a process with the specified - <c><anno>ServerName</anno></c> this function returns - <seealso marker="#type-start_ret"><c>{error,{already_started,Pid}}</c></seealso>, - where <c>Pid</c> is the <c>pid()</c> of that process. - </p> - <p> - If <c>Module:init/1</c> fails with <c>Reason</c>, - this function returns - <seealso marker="#type-start_ret"><c>{error,Reason}</c></seealso>. - If <c>Module:init/1</c> returns - <seealso marker="#type-start_ret"> - <c>{stop,Reason}</c> - </seealso> - or - <seealso marker="#type-start_ret"><c>ignore</c></seealso>, - the process is terminated and this function - returns - <seealso marker="#type-start_ret"> - <c>{error,Reason}</c> - </seealso> - or - <seealso marker="#type-start_ret"><c>ignore</c></seealso>, - respectively. - </p> - </desc> - </func> - - - <func> - <name name="start" arity="3" /> - <name name="start" arity="4" /> - <fsummary>Create a stand-alone <c>gen_statem</c> process</fsummary> - <desc> - <p> - Creates a stand-alone <c>gen_statem</c> process according to - OTP design principles (using - <seealso marker="proc_lib"><c>proc_lib</c></seealso> - 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. - </p> - <p> - See <seealso marker="#start_link/3"><c>start_link/3,4</c></seealso> - for a description of arguments and return values. - </p> - </desc> - </func> - - <func> - <name name="stop" arity="1" /> - <fsummary>Synchronously stop a generic server</fsummary> - <desc> - <p> - The same as - <seealso marker="#stop/3"> - <c>stop(<anno>ServerRef</anno>, normal, infinity)</c>. - </seealso> - </p> - </desc> - </func> - <func> - <name name="stop" arity="3" /> - <fsummary>Synchronously stop a generic server</fsummary> - <desc> - <p> - Orders the <c>gen_statem</c> - <seealso marker="#type-server_ref"> - <c><anno>ServerRef</anno></c> - </seealso> - to exit with the given <c><anno>Reason</anno></c> - and waits for it to terminate. - The <c>gen_statem</c> will call - <seealso marker="#Module:terminate/3"> - <c>Module:terminate/3</c> - </seealso> - before exiting. - </p> - <p> - This function returns <c>ok</c> if the server terminates - with the expected reason. Any other reason than <c>normal</c>, - <c>shutdown</c>, or <c>{shutdown,Term}</c> will cause an - error report to be issued through - <seealso marker="kernel:error_logger#format/2"> - <c>error_logger:format/2</c>. - </seealso> - The default <c><anno>Reason</anno></c> is <c>normal</c>. - </p> - <p> - <c><anno>Timeout</anno></c> is an integer greater than zero - which specifies how many milliseconds to wait for the server to - terminate, or the atom <c>infinity</c> to wait indefinitely. - The default value is <c>infinity</c>. - If the server has not terminated within the specified time, - a <c>timeout</c> exception is raised. - </p> - <p> - If the process does not exist, a <c>noproc</c> exception - is raised. - </p> - </desc> - </func> - <func> - <name name="call" arity="2" /> - <name name="call" arity="3" /> - <fsummary>Make a synchronous call to a <c>gen_statem</c></fsummary> + <name name="call" arity="2"/> + <name name="call" arity="3"/> + <fsummary>Make a synchronous call to a <c>gen_statem</c>.</fsummary> <desc> <p> Makes a synchronous call to the <c>gen_statem</c> - <seealso marker="#type-server_ref"> - <c><anno>ServerRef</anno></c> - </seealso> + <seealso marker="#type-server_ref"><c><anno>ServerRef</anno></c></seealso> by sending a request and waiting until its reply arrives. - The <c>gen_statem</c> will call the + The <c>gen_statem</c> calls the <seealso marker="#state_function">state function</seealso> with <seealso marker="#type-event_type"><c>event_type()</c></seealso> <c>{call,From}</c> and event content @@ -1108,43 +914,41 @@ handle_event(_, _, State, Data) -> and that <c><anno>Reply</anno></c> becomes the return value of this function. </p> - <p> - <c><anno>Timeout</anno></c> is an integer greater than zero + <p> + <c><anno>Timeout</anno></c> is an integer > 0, which specifies how many milliseconds to wait for a reply, or the atom <c>infinity</c> 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. </p> <note> <p> 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 <c><anno>Timeout</anno> =:= infinity</c>. </p> </note> - <p> - The call may fail for example if the <c>gen_statem</c> dies + <p> + The call can fail, for example, if the <c>gen_statem</c> dies before or during this function call. </p> </desc> </func> <func> - <name name="cast" arity="2" /> - <fsummary>Send an asynchronous event to a <c>gen_statem</c></fsummary> + <name name="cast" arity="2"/> + <fsummary>Send an asynchronous event to a <c>gen_statem</c>.</fsummary> <desc> <p> Sends an asynchronous event to the <c>gen_statem</c> - <seealso marker="#type-server_ref"> - <c><anno>ServerRef</anno></c> - </seealso> + <seealso marker="#type-server_ref"><c><anno>ServerRef</anno></c></seealso> and returns <c>ok</c> immediately, ignoring if the destination node or <c>gen_statem</c> does not exist. - The <c>gen_statem</c> will call the + The <c>gen_statem</c> calls the <seealso marker="#state_function">state function</seealso> with <seealso marker="#type-event_type"><c>event_type()</c></seealso> <c>cast</c> and event content @@ -1154,68 +958,29 @@ handle_event(_, _, State, Data) -> </func> <func> - <name name="reply" arity="1" /> - <name name="reply" arity="2" /> - <fsummary>Reply to a caller</fsummary> - <desc> - <p> - This function can be used by a <c>gen_statem</c> - to explicitly send a reply to a process that waits in - <seealso marker="#call/2"><c>call/2</c></seealso> - when the reply cannot be defined in - the return value of a - <seealso marker="#state_function">state function</seealso>. - </p> - <p> - <c><anno>From</anno></c> must be the term from the - <seealso marker="#type-event_type"> - <c>{call,<anno>From</anno>}</c> - </seealso> - argument to the - <seealso marker="#state_function">state function</seealso>. - <c><anno>From</anno></c> and <c><anno>Reply</anno></c> - can also be specified using a - <seealso marker="#type-reply_action"> - <c>reply_action()</c> - </seealso> - and multiple replies with a list of them. - </p> - <note> - <p> - A reply sent with this function will not be visible - in <seealso marker="sys"><c>sys</c></seealso> debug output. - </p> - </note> - </desc> - </func> - - <func> - <name name="enter_loop" arity="5" /> - <fsummary>Enter the <c>gen_statem</c> receive loop</fsummary> + <name name="enter_loop" arity="5"/> + <fsummary>Enter the <c>gen_statem</c> receive loop.</fsummary> <desc> <p> The same as <seealso marker="#enter_loop/7"><c>enter_loop/7</c></seealso> except that no - <seealso marker="#type-server_name"> - <c>server_name()</c> - </seealso> + <seealso marker="#type-server_name"><c>server_name()</c></seealso> must have been registered. </p> </desc> </func> + <func> - <name name="enter_loop" arity="6" /> - <fsummary>Enter the <c>gen_statem</c> receive loop</fsummary> + <name name="enter_loop" arity="6"/> + <fsummary>Enter the <c>gen_statem</c> receive loop.</fsummary> <desc> <p> - If <c><anno>Server_or_Actions</anno></c> is a <c>list()</c> + If <c><anno>Server_or_Actions</anno></c> is a <c>list()</c>, the same as <seealso marker="#enter_loop/7"><c>enter_loop/7</c></seealso> except that no - <seealso marker="#type-server_name"> - <c>server_name()</c> - </seealso> + <seealso marker="#type-server_name"><c>server_name()</c></seealso> must have been registered and <c>Actions = <anno>Server_or_Actions</anno></c>. </p> @@ -1228,73 +993,350 @@ handle_event(_, _, State, Data) -> </p> </desc> </func> + <func> - <name name="enter_loop" arity="7" /> - <fsummary>Enter the <c>gen_statem</c> receive loop</fsummary> + <name name="enter_loop" arity="7"/> + <fsummary>Enter the <c>gen_statem</c> receive loop.</fsummary> <desc> - <p> - Makes an the calling process become a <c>gen_statem</c>. - Does not return, instead the calling process will enter - the <c>gen_statem</c> receive loop and become + <p> + Makes the calling process become a <c>gen_statem</c>. + Does not return, instead the calling process enters + the <c>gen_statem</c> receive loop and becomes a <c>gen_statem</c> server. The process <em>must</em> have been started using one of the start functions in - <seealso marker="proc_lib"><c>proc_lib</c></seealso>. + <seealso marker="proc_lib"><c>proc_lib</c></seealso>. The user is responsible for any initialization of the process, including registering a name for it. </p> - <p> + <p> This function is useful when a more complex initialization - procedure is needed than - the <c>gen_statem</c> behaviour provides. + procedure is needed than + the <c>gen_statem</c> behavior provides. </p> - <p> - <c><anno>Module</anno></c>, <c><anno>Opts</anno></c> and + <p> + <c><anno>Module</anno></c>, <c><anno>Opts</anno></c>, and <c><anno>Server</anno></c> have the same meanings as when calling - <seealso marker="#start_link/3"> - <c>gen_statem:start[_link]/3,4</c>. - </seealso> - However, the - <seealso marker="#type-server_name"> - <c>server_name()</c> - </seealso> + <seealso marker="#start_link/3"><c>start[_link]/3,4</c></seealso>. + However, the + <seealso marker="#type-server_name"><c>server_name()</c></seealso> name must have been registered accordingly <em>before</em> this function is called.</p> <p> <c><anno>CallbackMode</anno></c>, <c><anno>State</anno></c>, - <c><anno>Data</anno></c> and <c><anno>Actions</anno></c> + <c><anno>Data</anno></c>, and <c><anno>Actions</anno></c> have the same meanings as in the return value of - <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>. - Also, the callback module <c><anno>Module</anno></c> + <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>. + Also, the callback module <c><anno>Module</anno></c> does not need to export an <c>init/1</c> function. </p> <p> - Failure: If the calling process was not started by a - <seealso marker="proc_lib"><c>proc_lib</c></seealso> + The function fails if the calling process was not started by a + <seealso marker="proc_lib"><c>proc_lib</c></seealso> start function, or if it is not registered - according to + according to <seealso marker="#type-server_name"><c>server_name()</c></seealso>. </p> </desc> </func> - </funcs> + <func> + <name name="reply" arity="1"/> + <name name="reply" arity="2"/> + <fsummary>Reply to a caller.</fsummary> + <desc> + <p> + This function can be used by a <c>gen_statem</c> + to explicitly send a reply to a process that waits in + <seealso marker="#call/2"><c>call/2</c></seealso> + when the reply cannot be defined in + the return value of a + <seealso marker="#state_function">state function</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_function">state function</seealso>. + <c><anno>From</anno></c> and <c><anno>Reply</anno></c> + can also be specified using a + <seealso marker="#type-reply_action"><c>reply_action()</c></seealso> + and multiple replies with a list of them. + </p> + <note> + <p> + A reply sent with this function is not visible + in <seealso marker="sys"><c>sys</c></seealso> debug output. + </p> + </note> + </desc> + </func> + <func> + <name name="start" arity="3"/> + <name name="start" arity="4"/> + <fsummary>Create a standalone <c>gen_statem</c> process.</fsummary> + <desc> + <p> + Creates a standalone <c>gen_statem</c> process according to + OTP design principles (using + <seealso marker="proc_lib"><c>proc_lib</c></seealso> + primitives). + As it does not get linked to the calling process, + this start function cannot be used by a supervisor + to start a child. + </p> + <p> + For a description of arguments and return values, see + <seealso marker="#start_link/3"><c>start_link/3,4</c></seealso>. + </p> + </desc> + </func> + <func> + <name name="start_link" arity="3"/> + <name name="start_link" arity="4"/> + <fsummary>Create a linked <c>gen_statem</c> process.</fsummary> + <desc> + <p> + Creates a <c>gen_statem</c> process according + to OTP design principles + (using + <seealso marker="proc_lib"><c>proc_lib</c></seealso> + primitives) + that is linked to the calling process. + This is essential when the <c>gen_statem</c> must be part of + a supervision tree so it gets linked to its supervisor. + </p> + <p> + The <c>gen_statem</c> process calls + <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> + to initialize the server. To ensure a synchronized startup + procedure, <c>start_link/3,4</c> does not return until + <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> + has returned. + </p> + <p> + <c><anno>ServerName</anno></c> specifies the + <seealso marker="#type-server_name"><c>server_name()</c></seealso> + to register for the <c>gen_statem</c>. + If the <c>gen_statem</c> is started with <c>start_link/3</c>, + no <c><anno>ServerName</anno></c> is provided and + the <c>gen_statem</c> is not registered. + </p> + <p><c><anno>Module</anno></c> is the name of the callback module.</p> + <p> + <c><anno>Args</anno></c> is an arbitrary term that is passed as + the argument to + <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>. + </p> + <list type="bulleted"> + <item> + <p> + If option <c>{timeout,Time}</c> is present in + <c><anno>Opts</anno></c>, the <c>gen_statem</c> + is allowed to spend <c>Time</c> milliseconds initializing + or it terminates and the start function returns + <seealso marker="#type-start_ret"><c>{error,timeout}</c></seealso>. + </p> + </item> + <item> + <p> + If option + <seealso marker="#type-debug_opt"><c>{debug,Dbgs}</c></seealso> + is present in <c><anno>Opts</anno></c>, debugging through + <seealso marker="sys"><c>sys</c></seealso> is activated. + </p> + </item> + <item> + <p> + If option <c>{spawn_opt,SpawnOpts}</c> is present in + <c><anno>Opts</anno></c>, <c>SpawnOpts</c> is passed + as option list to + <seealso marker="erts:erlang#spawn_opt/2"><c>erlang:spawn_opt/2</c></seealso>, + which is used to spawn the <c>gen_statem</c> process. + </p> + </item> + </list> + <note> + <p> + Using spawn option <c>monitor</c> is not + allowed, it causes this function to fail with reason + <c>badarg</c>. + </p> + </note> + <p> + If the <c>gen_statem</c> is successfully created + and initialized, this function returns + <seealso marker="#type-start_ret"><c>{ok,Pid}</c></seealso>, + where <c>Pid</c> is the <c>pid()</c> + of the <c>gen_statem</c>. + If a process with the specified <c><anno>ServerName</anno></c> + exists already, this function returns + <seealso marker="#type-start_ret"><c>{error,{already_started,Pid}}</c></seealso>, + where <c>Pid</c> is the <c>pid()</c> of that process. + </p> + <p> + If <c>Module:init/1</c> fails with <c>Reason</c>, + this function returns + <seealso marker="#type-start_ret"><c>{error,Reason}</c></seealso>. + If <c>Module:init/1</c> returns + <seealso marker="#type-start_ret"><c>{stop,Reason}</c></seealso> + or + <seealso marker="#type-start_ret"><c>ignore</c></seealso>, + the process is terminated and this function + returns + <seealso marker="#type-start_ret"><c>{error,Reason}</c></seealso> + or + <seealso marker="#type-start_ret"><c>ignore</c></seealso>, + respectively. + </p> + </desc> + </func> + + <func> + <name name="stop" arity="1"/> + <fsummary>Synchronously stop a generic server.</fsummary> + <desc> + <p> + The same as + <seealso marker="#stop/3"><c>stop(<anno>ServerRef</anno>, normal, infinity)</c></seealso>. + </p> + </desc> + </func> + + <func> + <name name="stop" arity="3"/> + <fsummary>Synchronously stop a generic server.</fsummary> + <desc> + <p> + Orders the <c>gen_statem</c> + <seealso marker="#type-server_ref"><c><anno>ServerRef</anno></c></seealso> + to exit with the specified <c><anno>Reason</anno></c> + and waits for it to terminate. + The <c>gen_statem</c> calls + <seealso marker="#Module:terminate/3"><c>Module:terminate/3</c></seealso> + before exiting. + </p> + <p> + This function returns <c>ok</c> if the server terminates + with the expected reason. Any other reason than <c>normal</c>, + <c>shutdown</c>, or <c>{shutdown,Term}</c> causes an + error report to be issued through + <seealso marker="kernel:error_logger#format/2"><c>error_logger:format/2</c></seealso>. + The default <c><anno>Reason</anno></c> is <c>normal</c>. + </p> + <p> + <c><anno>Timeout</anno></c> is an integer > 0, + which specifies how many milliseconds to wait for the server to + terminate, or the atom <c>infinity</c> to wait indefinitely. + Defaults to <c>infinity</c>. + If the server does not terminate within the specified time, + a <c>timeout</c> exception is raised. + </p> + <p> + If the process does not exist, a <c>noproc</c> exception + is raised. + </p> + </desc> + </func> + </funcs> <section> - <title>CALLBACK FUNCTIONS</title> + <title>Callback Functions</title> <p> - The following functions should be exported from a + The following functions are to be exported from a <c>gen_statem</c> callback module. </p> </section> + <funcs> + <func> + <name>Module:code_change(OldVsn, OldState, OldData, Extra) -> + Result + </name> + <fsummary>Update the internal state during upgrade/downgrade.</fsummary> + <type> + <v>OldVsn = Vsn | {down,Vsn}</v> + <v> Vsn = term()</v> + <v>OldState = NewState = term()</v> + <v>Extra = term()</v> + <v>Result = {NewCallbackMode,NewState,NewData} | Reason</v> + <v> + NewCallbackMode = + <seealso marker="#type-callback_mode">callback_mode()</seealso> + </v> + <v> + OldState = NewState = + <seealso marker="#type-state">state()</seealso> + </v> + <v> + OldData = NewData = + <seealso marker="#type-data">data()</seealso> + </v> + <v>Reason = term()</v> + </type> + <desc> + <p> + 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 + <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>. + </p> + <p> + For an upgrade, <c>OldVsn</c> is <c>Vsn</c>, and + for a downgrade, <c>OldVsn</c> is + <c>{down,Vsn}</c>. <c>Vsn</c> is defined by the <c>vsn</c> + attribute(s) of the old version of the callback module + <c>Module</c>. If no such attribute is defined, the version + is the checksum of the Beam file. + </p> + <note> + <p> + If you would dare to change + <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> + during release upgrade/downgrade, the upgrade is no problem, + as the new code surely knows what <em>callback mode</em> + it needs. However, for a downgrade this function must + know from argument <c>Extra</c> that comes from the + <seealso marker="sasl:appup"><c>sasl:appup</c></seealso> + file what <em>callback mode</em> the old code did use. + It can also be possible to figure this out + from argument <c>{down,Vsn}</c>, as <c>Vsn</c> + in effect defines the old callback module version. + </p> + </note> + <p> + <c>OldState</c> and <c>OldData</c> is the internal state + of the <c>gen_statem</c>. + </p> + <p> + <c>Extra</c> is passed "as is" from the <c>{advanced,Extra}</c> + part of the update instruction. + </p> + <p> + If successful, the function must return the updated + internal state in an + <c>{NewCallbackMode,NewState,NewData}</c> tuple. + </p> + <p> + If the function returns <c>Reason</c>, the ongoing + upgrade fails and rolls back to the old release.</p> + <p> + This function can use + <seealso marker="erts:erlang#throw/1"><c>erlang:throw/1</c></seealso> + to return <c>Result</c> or <c>Reason</c>. + </p> + </desc> + </func> <func> <name>Module:init(Args) -> Result</name> - <fsummary>Initialize process and internal state</fsummary> + <fsummary>Initialize process and internal state.</fsummary> <type> <v>Args = term()</v> <v>Result = {CallbackMode,State,Data}</v> @@ -1316,25 +1358,25 @@ handle_event(_, _, State, Data) -> <v>Reason = term()</v> </type> <desc> - <marker id="Module:init-1" /> - <p> + <marker id="Module:init-1"/> + <p> Whenever a <c>gen_statem</c> is started using - <seealso marker="#start_link/3"><c>start_link/3,4</c></seealso> + <seealso marker="#start_link/3"><c>start_link/3,4</c></seealso> or - <seealso marker="#start/3"><c>start/3,4</c></seealso>, - this function is called by the new process to initialize + <seealso marker="#start/3"><c>start/3,4</c></seealso>, + this function is called by the new process to initialize the implementation state and server data. </p> - <p> + <p> <c>Args</c> is the <c>Args</c> argument provided to the start - function. + function. </p> - <p> - If the initialization is successful, the function should - return <c>{CallbackMode,State,Data}</c> or + <p> + If the initialization is successful, the function is to + return <c>{CallbackMode,State,Data}</c> or <c>{CallbackMode,State,Data,Actions}</c>. <c>CallbackMode</c> selects the - <seealso marker="#type-callback_mode"><em>callback mode</em></seealso>. + <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> of the <c>gen_statem</c>. <c>State</c> is the initial <seealso marker="#type-state"><c>state()</c></seealso> @@ -1347,28 +1389,127 @@ handle_event(_, _, State, Data) -> <seealso marker="#type-state">state</seealso> just as for a <seealso marker="#state_function">state function</seealso>. </p> - <p> - If something goes wrong during the initialization - the function should return <c>{stop,Reason}</c> - or <c>ignore</c>. See + <p> + If the initialization fails, + the function is to return <c>{stop,Reason}</c> + or <c>ignore</c>; see <seealso marker="#start_link/3"><c>start_link/3,4</c></seealso>. </p> <p> - This function may use - <seealso marker="erts:erlang#throw/1"><c>throw/1</c></seealso> + This function can use + <seealso marker="erts:erlang#throw/1"><c>erlang:throw/1</c></seealso> to return <c>Result</c>. </p> </desc> </func> <func> + <name>Module:format_status(Opt, [PDict,State,Data]) -> + Status + </name> + <fsummary>Optional function for providing a term describing the + current <c>gen_statem</c> status.</fsummary> + <type> + <v>Opt = normal | terminate</v> + <v>PDict = [{Key, Value}]</v> + <v> + State = + <seealso marker="#type-state">state()</seealso> + </v> + <v> + Data = + <seealso marker="#type-data">data()</seealso> + </v> + <v>Key = term()</v> + <v>Value = term()</v> + <v>Status = term()</v> + </type> + <desc> + <note> + <p> + This callback is optional, so a callback module does not need + to export it. The <c>gen_statem</c> module provides a default + implementation of this function that returns + <c>{State,Data}</c>. If this callback fails, the default + function returns <c>{State,Info}</c>, + where <c>Info</c> informs of the crash but no details, + to hide possibly sensitive data. + </p> + </note> + <p>This function is called by a <c>gen_statem</c> process when + any of the following apply:</p> + <list type="bulleted"> + <item> + One of + <seealso marker="sys#get_status/1"><c>sys:get_status/1,2</c></seealso> + is invoked to get the <c>gen_statem</c> status. <c>Opt</c> is set + to the atom <c>normal</c> for this case. + </item> + <item> + The <c>gen_statem</c> terminates abnormally and logs an error. + <c>Opt</c> is set to the atom <c>terminate</c> for this case. + </item> + </list> + <p> + This function is useful for changing the form and + appearance of the <c>gen_statem</c> status for these cases. A + callback module wishing to change the + <seealso marker="sys#get_status/1"><c>sys:get_status/1,2</c></seealso> + return value and how + its status appears in termination error logs exports an + instance of <c>format_status/2</c>, which returns a term + describing the current status of the <c>gen_statem</c>. + </p> + <p> + <c>PDict</c> is the current value of the process dictionary + of the <c>gen_statem</c>. + </p> + <p> + <seealso marker="#type-state"><c>State</c></seealso> + is the internal state of the <c>gen_statem</c>. + </p> + <p> + <seealso marker="#type-data"><c>Data</c></seealso> + is the internal server data of the <c>gen_statem</c>. + </p> + <p> + The function is to return <c>Status</c>, a term that + changes the details of the current state and status of + the <c>gen_statem</c>. There are no restrictions on the + form <c>Status</c> can take, but for the + <seealso marker="sys#get_status/1"><c>sys:get_status/1,2</c></seealso> + case (when <c>Opt</c> + is <c>normal</c>), the recommended form for + the <c>Status</c> value is <c>[{data, [{"State", + Term}]}]</c>, where <c>Term</c> provides relevant details of + the <c>gen_statem</c> state. Following this recommendation is not + required, but it makes the callback module status + consistent with the rest of the + <seealso marker="sys#get_status/1"><c>sys:get_status/1,2</c></seealso> + return value. + </p> + <p> + One use for this function is to return compact alternative + state representations to avoid having large state terms + printed in log files. Another use is to hide sensitive data from + being written to the error log. + </p> + <p> + This function can use + <seealso marker="erts:erlang#throw/1"><c>erlang:throw/1</c></seealso> + to return <c>Status</c>. + </p> + </desc> + </func> + + <func> <name>Module:StateName(EventType, EventContent, Data) -> - StateFunctionResult + StateFunctionResult </name> <name>Module:handle_event(EventType, EventContent, - State, Data) -> HandleEventResult + State, Data) -> HandleEventResult </name> - <fsummary>Handle an event</fsummary> + <fsummary>Handle an event.</fsummary> <type> <v> EventType = @@ -1385,59 +1526,55 @@ handle_event(_, _, State, Data) -> </v> <v> StateFunctionResult = - <seealso marker="#type-state_function_result"> - state_function_result() - </seealso> + <seealso marker="#type-state_function_result">state_function_result()</seealso> </v> <v> HandleEventResult = - <seealso marker="#type-handle_event_result"> - handle_event_result() - </seealso> + <seealso marker="#type-handle_event_result">handle_event_result()</seealso> </v> </type> <desc> - <p> + <p> Whenever a <c>gen_statem</c> receives an event from - <seealso marker="#call/2"><c>call/2</c></seealso>, - <seealso marker="#cast/2"><c>cast/2</c></seealso> or - as a normal process message one of these functions is called. If + <seealso marker="#call/2"><c>call/2</c></seealso>, + <seealso marker="#cast/2"><c>cast/2</c></seealso>, or + as a normal process message, one of these functions is called. If <seealso marker="#type-callback_mode"><em>callback mode</em></seealso> - is <c>state_functions</c> then <c>Module:StateName/3</c> is called, - and if it is <c>handle_event_function</c> - then <c>Module:handle_event/4</c> is called. + is <c>state_functions</c>, <c>Module:StateName/3</c> is called, + and if it is <c>handle_event_function</c>, + <c>Module:handle_event/4</c> is called. </p> <p> If <c>EventType</c> is - <seealso marker="#type-event_type"><c>{call,From}</c></seealso> - the caller is waiting for a reply. The reply can be sent + <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_function">state function</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> + <seealso marker="#type-reply_action"><c>Replies</c></seealso>, or by calling <seealso marker="#reply/2"><c>reply(From, Reply)</c></seealso>. </p> <p> If this function returns with a next state that - does not match equal (<c>=/=</c>) to the current state - all postponed events will be retried in the next state. + does not match equal (<c>=/=</c>) to the current state, + all postponed events are retried in the next state. </p> <p> The only difference between <c>StateFunctionResult</c> and <c>HandleEventResult</c> is that for <c>StateFunctionResult</c> - the next state has to be an atom but for <c>HandleEventResult</c> + the next state must be an atom, but for <c>HandleEventResult</c> there is no restriction on the next state. </p> <p> - See <seealso marker="#type-action"><c>action()</c></seealso> - for options that can be set and actions that can be done - by <c>gen_statem</c> after returning from this function. + For options that can be set and actions that can be done + by <c>gen_statem</c> after returning from this function, + see <seealso marker="#type-action"><c>action()</c></seealso>. </p> <p> - These functions may use - <seealso marker="erts:erlang#throw/1"><c>throw/1</c></seealso>, + These functions can use + <seealso marker="erts:erlang#throw/1"><c>erlang:throw/1</c></seealso>, to return the result. </p> </desc> @@ -1445,7 +1582,7 @@ handle_event(_, _, State, Data) -> <func> <name>Module:terminate(Reason, State, Data) -> Ignored</name> - <fsummary>Clean up before termination</fsummary> + <fsummary>Clean up before termination.</fsummary> <type> <v>Reason = normal | shutdown | {shutdown,term()} | term()</v> <v>State = <seealso marker="#type-state">state()</seealso></v> @@ -1453,272 +1590,82 @@ handle_event(_, _, State, Data) -> <v>Ignored = term()</v> </type> <desc> - <p> + <p> This function is called by a <c>gen_statem</c> - when it is about to terminate. It should be the opposite of + when it is about to terminate. It is to be the opposite of <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> - and do any necessary cleaning up. When it returns, - the <c>gen_statem</c> terminates with <c>Reason</c>. The return - value is ignored.</p> - <p> + and do any necessary cleaning up. When it returns, + the <c>gen_statem</c> terminates with <c>Reason</c>. The return + value is ignored.</p> + <p> <c>Reason</c> is a term denoting the stop reason and - <seealso marker="#type-state"><c>State</c></seealso> + <seealso marker="#type-state"><c>State</c></seealso> is the internal state of the <c>gen_statem</c>. </p> - <p> + <p> <c>Reason</c> depends on why the <c>gen_statem</c> is terminating. - If it is because another callback function has returned a - stop tuple <c>{stop,Reason}</c> in + If it is because another callback function has returned, a + stop tuple <c>{stop,Reason}</c> in <seealso marker="#type-action"><c>Actions</c></seealso>, - <c>Reason</c> will have the value specified in that tuple. - If it is due to a failure, <c>Reason</c> is the error reason. + <c>Reason</c> has the value specified in that tuple. + If it is because of a failure, <c>Reason</c> is the error reason. </p> <p> If the <c>gen_statem</c> is part of a supervision tree and is - ordered by its supervisor to terminate, this function will be - called with <c>Reason = shutdown</c> if the following + ordered by its supervisor to terminate, this function is + called with <c>Reason = shutdown</c> if both the following conditions apply:</p> <list type="bulleted"> <item> - the <c>gen_statem</c> has been set - to trap exit signals, and + <p> + The <c>gen_statem</c> has been set + to trap exit signals. + </p> </item> <item> - the shutdown strategy as defined in the supervisor's - child specification is an integer timeout value, not - <c>brutal_kill</c>. + <p> + The shutdown strategy as defined in the supervisor's + child specification is an integer time-out value, not + <c>brutal_kill</c>. + </p> </item> </list> <p> Even if the <c>gen_statem</c> is <em>not</em> - part of a supervision tree, this function will be called + part of a supervision tree, this function is called if it receives an <c>'EXIT'</c> message from its parent. - <c>Reason</c> will be the same as + <c>Reason</c> is the same as in the <c>'EXIT'</c> message. </p> <p> - Otherwise, the <c>gen_statem</c> will be immediately terminated. + Otherwise, the <c>gen_statem</c> is immediately terminated. </p> <p> - Note that for any other reason than <c>normal</c>, - <c>shutdown</c>, or <c>{shutdown,Term}</c> - the <c>gen_statem</c> is assumed to terminate due to an error + Notice that for any other reason than <c>normal</c>, + <c>shutdown</c>, or <c>{shutdown,Term}</c>, + the <c>gen_statem</c> is assumed to terminate because of an error and an error report is issued using - <seealso marker="kernel:error_logger#format/2"> - <c>error_logger:format/2</c>. - </seealso> + <seealso marker="kernel:error_logger#format/2"><c>error_logger:format/2</c></seealso>. </p> <p> - This function may use - <seealso marker="erts:erlang#throw/1"><c>throw/1</c></seealso> + This function can use + <seealso marker="erts:erlang#throw/1"><c>erlang:throw/1</c></seealso> to return <c>Ignored</c>, which is ignored anyway. </p> </desc> </func> - - <func> - <name>Module:code_change(OldVsn, OldState, OldData, Extra) -> - Result - </name> - <fsummary>Update the internal state during upgrade/downgrade</fsummary> - <type> - <v>OldVsn = Vsn | {down,Vsn}</v> - <v> Vsn = term()</v> - <v>OldState = NewState = term()</v> - <v>Extra = term()</v> - <v>Result = {NewCallbackMode,NewState,NewData} | Reason</v> - <v> - NewCallbackMode = - <seealso marker="#type-callback_mode">callback_mode()</seealso> - </v> - <v> - OldState = NewState = - <seealso marker="#type-state">state()</seealso> - </v> - <v> - OldData = NewData = - <seealso marker="#type-data">data()</seealso> - </v> - <v>Reason = term()</v> - </type> - <desc> - <p> - This function is called by a <c>gen_statem</c> when it should - 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 given in the - <seealso marker="sasl:appup"><c>appup</c></seealso> - file. See - <seealso marker="doc/design_principles:release_handling#instr"> - OTP Design Principles - </seealso> - for more information. - </p> - <p> - In the case of an upgrade, <c>OldVsn</c> is <c>Vsn</c>, and - in the case of a downgrade, <c>OldVsn</c> is - <c>{down,Vsn}</c>. <c>Vsn</c> is defined by the <c>vsn</c> - attribute(s) of the old version of the callback module - <c>Module</c>. If no such attribute is defined, the version - is the checksum of the BEAM file. - </p> - <note> - <p> - If you would dare to change - <seealso marker="#type-callback_mode"> - <em>callback mode</em> - </seealso> - during release upgrade/downgrade, the upgrade is no problem - since the new code surely knows what <em>callback mode</em> - it needs, but for a downgrade this function will have to - know from the <c>Extra</c> argument that comes from the - <seealso marker="sasl:appup"><c>appup</c></seealso> - file what <em>callback mode</em> the old code did use. - It may also be possible to figure this out - from the <c>{down,Vsn}</c> argument since <c>Vsn</c> - in effect defines the old callback module version. - </p> - </note> - <p> - <c>OldState</c> and <c>OldData</c> is the internal state - of the <c>gen_statem</c>. - </p> - <p> - <c>Extra</c> is passed as-is from the <c>{advanced,Extra}</c> - part of the update instruction. - </p> - <p> - If successful, the function shall return the updated - internal state in an - <c>{NewCallbackMode,NewState,NewData}</c> tuple. - </p> - <p> - If the function returns <c>Reason</c>, the ongoing - upgrade will fail and roll back to the old release.</p> - <p> - This function may use - <seealso marker="erts:erlang#throw/1"><c>throw/1</c></seealso> - to return <c>Result</c> or <c>Reason</c>. - </p> - </desc> - </func> - - <func> - <name>Module:format_status(Opt, [PDict,State,Data]) -> - Status - </name> - <fsummary>Optional function for providing a term describing the - current <c>gen_statem</c> status</fsummary> - <type> - <v>Opt = normal | terminate</v> - <v>PDict = [{Key, Value}]</v> - <v> - State = - <seealso marker="#type-state">state()</seealso> - </v> - <v> - Data = - <seealso marker="#type-data">data()</seealso> - </v> - <v>Key = term()</v> - <v>Value = term()</v> - <v>Status = term()</v> - </type> - <desc> - <note> - <p> - This callback is optional, so a callback module need not - export it. The <c>gen_statem</c> module provides a default - implementation of this function that returns - <c>{State,Data}</c>. If this callback fails the default - function will return <c>{State,Info}</c> - where <c>Info</c> informs of the crash but no details, - to hide possibly sensitive data. - </p> - </note> - <p>This function is called by a <c>gen_statem</c> process when:</p> - <list type="bulleted"> - <item> - One of - <seealso marker="sys#get_status/1"> - <c>sys:get_status/1,2</c> - </seealso> - is invoked to get the <c>gen_statem</c> status. <c>Opt</c> is set - to the atom <c>normal</c> for this case. - </item> - <item> - The <c>gen_statem</c> terminates abnormally and logs an error. - <c>Opt</c> is set to the atom <c>terminate</c> for this case. - </item> - </list> - <p> - This function is useful for customising the form and - appearance of the <c>gen_statem</c> status for these cases. A - callback module wishing to customise the - <seealso marker="sys#get_status/1"> - <c>sys:get_status/1,2</c> - </seealso> - return value as well as how - its status appears in termination error logs exports an - instance of <c>format_status/2</c> that returns a term - describing the current status of the <c>gen_statem</c>. - </p> - <p> - <c>PDict</c> is the current value of the <c>gen_statem</c>'s - process dictionary. - </p> - <p> - <seealso marker="#type-state"><c>State</c></seealso> - is the internal state of the <c>gen_statem</c>. - </p> - <p> - <seealso marker="#type-data"><c>Data</c></seealso> - is the internal server data of the <c>gen_statem</c>. - </p> - <p> - The function should return <c>Status</c>, a term that - customises the details of the current state and status of - the <c>gen_statem</c>. There are no restrictions on the - form <c>Status</c> can take, but for the - <seealso marker="sys#get_status/1"> - <c>sys:get_status/1,2</c> - </seealso> - case (when <c>Opt</c> - is <c>normal</c>), the recommended form for - the <c>Status</c> value is <c>[{data, [{"State", - Term}]}]</c> where <c>Term</c> provides relevant details of - the <c>gen_statem</c> state. Following this recommendation isn't - required, but doing so will make the callback module status - consistent with the rest of the - <seealso marker="sys#get_status/1"> - <c>sys:get_status/1,2</c> - </seealso> - return value. - </p> - <p> - 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 - being written to the error log. - </p> - <p> - This function may use - <seealso marker="erts:erlang#throw/1"><c>throw/1</c></seealso> - to return <c>Status</c>. - </p> - </desc> - </func> - </funcs> <section> - <title>SEE ALSO</title> - <p><seealso marker="gen_event"><c>gen_event(3)</c></seealso>, + <title>See Also</title> + <p> + <seealso marker="gen_event"><c>gen_event(3)</c></seealso>, <seealso marker="gen_fsm"><c>gen_fsm(3)</c></seealso>, <seealso marker="gen_server"><c>gen_server(3)</c></seealso>, - <seealso marker="supervisor"><c>supervisor(3)</c></seealso>, <seealso marker="proc_lib"><c>proc_lib(3)</c></seealso>, - <seealso marker="sys"><c>sys(3)</c></seealso></p> + <seealso marker="supervisor"><c>supervisor(3)</c></seealso>, + <seealso marker="sys"><c>sys(3)</c></seealso>. + </p> </section> </erlref> |