aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/doc/src/gen_statem.xml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib/doc/src/gen_statem.xml')
-rw-r--r--lib/stdlib/doc/src/gen_statem.xml1724
1 files changed, 1724 insertions, 0 deletions
diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml
new file mode 100644
index 0000000000..ec7f267c64
--- /dev/null
+++ b/lib/stdlib/doc/src/gen_statem.xml
@@ -0,0 +1,1724 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2016</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ </legalnotice>
+
+ <title>gen_statem</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <module>gen_statem</module>
+ <modulesummary>Generic State Machine Behaviour</modulesummary>
+ <description>
+ <p>
+ A behaviour module for implementing 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"...
+ </p>
+ <p>
+ The <c>gen_statem</c> behaviour 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:
+ </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>
+ </list>
+ <p>
+ The callback model(s) for <c>gen_statem</c> differs from
+ the one for <seealso marker="gen_fsm"><c>gen_fsm</c></seealso>,
+ but it is still fairly easy to rewrite
+ from <c>gen_fsm</c> to <c>gen_statem</c>.
+ </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.
+ </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>
+ <pre>
+gen_statem module Callback module
+----------------- ---------------
+gen_statem:start
+gen_statem:start_link -----> Module:init/1
+
+gen_statem:stop -----> Module:terminate/3
+
+gen_statem:call
+gen_statem:cast
+erlang:send
+erlang:'!' -----> Module:StateName/3
+ Module:handle_event/4
+
+- -----> Module:terminate/3
+
+- -----> Module:code_change/4</pre>
+ <p>
+ Events are of different
+ <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.
+ </p>
+ <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
+ <seealso marker="#type-callback_mode"><em>callback mode</em></seealso>
+ that the implementation specifies when the 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>.
+ 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.
+ </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
+ and the state function name is
+ <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
+ 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
+ so it is not retried in the current state.
+ After a state change the queue restarts with the postponed events.
+ </p>
+ <p>
+ 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
+ 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>
+ 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 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>
+ 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>
+ <p>
+ See the type
+ <seealso marker="#type-transition_option">
+ <c>transition_option()</c>
+ </seealso>
+ for the details of a state transition.
+ </p>
+ <p>
+ A <c>gen_statem</c> handles system messages as documented in
+ <seealso marker="sys"><c>sys</c></seealso>.
+ 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
+ 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>.
+ </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.
+ </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>
+ 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
+ while the server is expected to be idle for a long time.
+ However, use this feature with care
+ since hibernation can be too costly
+ to use after every event; see
+ <seealso marker="erts:erlang#hibernate/3">
+ <c>erlang:hibernate/3</c>.
+ </seealso>
+ </p>
+ </description>
+
+ <section>
+ <title>EXAMPLE</title>
+ <p>
+ This 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.
+ </p>
+ <p>This is the complete callback module file <c>pushbutton.erl</c>:</p>
+ <code type="erl">
+-module(pushbutton).
+-behaviour(gen_statem).
+
+-export([start/0,push/0,get_count/0,stop/0]).
+-export([terminate/3,code_change/4,init/1]).
+-export([on/3,off/3]).
+
+name() -> pushbutton_statem. % The registered server name
+callback_mode() -> state_functions.
+
+%% API. This example uses a registered name name()
+%% and does not link to the caller.
+start() ->
+ gen_statem:start({local,name()}, ?MODULE, [], []).
+push() ->
+ gen_statem:call(name(), push).
+get_count() ->
+ gen_statem:call(name(), get_count).
+stop() ->
+ gen_statem:stop(name()).
+
+%% Mandatory callback functions
+terminate(_Reason, _State, _Data) ->
+ void.
+code_change(_Vsn, State, Data, _Extra) ->
+ {callback_mode(),State,Data}.
+init([]) ->
+ %% Set the callback mode and initial state + data.
+ %% Data is used only as a counter.
+ State = off, Data = 0,
+ {callback_mode(),State,Data}.
+
+
+%%% State functions
+
+off({call,From}, push, Data) ->
+ %% Go to 'on', increment count and reply
+ %% that the resulting status is 'on'
+ {next_state,on,Data+1,[{reply,From,on}]};
+off(EventType, EventContent, Data) ->
+ handle_event(EventType, EventContent, Data).
+
+on({call,From}, push, Data) ->
+ %% Go to 'off' and reply that the resulting status is 'off'
+ {next_state,off,Data,[{reply,From,off}]};
+on(EventType, EventContent, Data) ->
+ handle_event(EventType, EventContent, Data).
+
+%% Handle events common to all states
+handle_event({call,From}, get_count, Data) ->
+ %% Reply with the current count
+ {keep_state,Data,[{reply,From,Data}]};
+handle_event(_, _, Data) ->
+ %% Ignore all other events
+ {keep_state,Data}.
+ </code>
+ <p>And this is a shell session when running it:</p>
+ <pre>
+1> pushbutton:start().
+{ok,&lt;0.36.0>}
+2> pushbutton:get_count().
+0
+3> pushbutton:push().
+on
+4> pushbutton:get_count().
+1
+5> pushbutton:push().
+off
+6> pushbutton:get_count().
+1
+7> pushbutton:stop().
+ok
+8> pushbutton:push().
+** exception exit: {noproc,{gen_statem,call,[pushbutton_statem,push,infinity]}}
+ 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
+ <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>
+ example file above:
+ </p>
+ <code type="erl">
+init([]) ->
+ %% Set the callback mode and initial state + data.
+ %% Data is used only as a counter.
+ State = off, Data = 0,
+ {handle_event_function,State,Data}.
+
+
+%%% Event handling
+
+handle_event({call,From}, push, off, Data) ->
+ %% Go to 'on', increment count and reply
+ %% that the resulting status is 'on'
+ {next_state,on,Data+1,[{reply,From,on}]};
+handle_event({call,From}, push, on, Data) ->
+ %% Go to 'off' and reply that the resulting status is 'off'
+ {next_state,off,Data,[{reply,From,off}]};
+%%
+%% Event handling common to all states
+handle_event({call,From}, get_count, State, Data) ->
+ %% Reply with the current count
+ {next_state,State,Data,[{reply,From,Data}]};
+handle_event(_, _, State, Data) ->
+ %% Ignore all other events
+ {next_state,State,Data}.
+ </code>
+ </section>
+
+ <datatypes>
+ <datatype>
+ <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>
+ and
+ <seealso marker="#type-server_ref">
+ <c>server_ref()</c>
+ </seealso> below.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <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>
+ 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>Name, Node</c></tag>
+ <item>
+ The <c>gen_statem</c> is locally registered
+ on another node.
+ </item>
+ <tag><c>GlobalName</c></tag>
+ <item>
+ The <c>gen_statem</c> is globally registered
+ in <seealso marker="kernel:global"><c>global</c></seealso>.
+ </item>
+ <tag><c>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>.
+ </item>
+ </taglist>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="debug_opt" />
+ <desc>
+ <p>
+ Debug option that can be used when starting
+ 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>
+ the corresponding function in
+ <seealso marker="sys"><c>sys</c></seealso> will be called.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="start_opt" />
+ <desc>
+ <p>
+ Options that can be used when starting
+ 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" />
+ <desc>
+ <p>
+ 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" />
+ <desc>
+ <p>
+ 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>.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="state" />
+ <desc>
+ <p>
+ After a state change (<c>NextState =/= State</c>)
+ all postponed events are retried.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <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.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="data" />
+ <desc>
+ <p>
+ A term in which the state machine implementation
+ should 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
+ in this data would change the set of events that
+ are handled than that data item should be made
+ a part of the state.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <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>.
+ <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.
+ 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
+ <c>timeout</c> and <c>internal</c> to itself.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <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>,
+ and with the return value from
+ <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.
+ </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.
+ </item>
+ </taglist>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="transition_option" />
+ <desc>
+ <p>
+ Transition options may be set by
+ <seealso marker="#type-action">actions</seealso>
+ and they modify some details below 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.
+ </item>
+ <item>
+ If
+ <seealso marker="#type-postpone">
+ <c>postpone()</c>
+ </seealso>
+ is <c>true</c>
+ the current event is postponed.
+ </item>
+ <item>
+ If the state changes the queue of incoming events
+ is reset to start with the oldest postponed.
+ </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.
+ </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.
+ </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.
+ </item>
+ </list>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="postpone" />
+ <desc>
+ <p>
+ If <c>true</c> postpone the current event and retry
+ it when the state changes
+ (<c>NextState =/= State</c>).
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="hibernate" />
+ <desc>
+ <p>
+ If <c>true</c> hibernate the <c>gen_statem</c>
+ by calling
+ <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
+ 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" />
+ <desc>
+ <p>
+ Generate 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.
+ </p>
+ <p>
+ If the value is <c>infinity</c> no timer is started since
+ it will never trigger 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.
+ </p>
+ <p>
+ Note that it is not possible nor needed to cancel this timeout
+ since it is cancelled automatically by any other event.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="action" />
+ <desc>
+ <p>
+ These state transition actions may be invoked by
+ returning them from the
+ <seealso marker="#state_function">state function</seealso>,
+ from <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
+ or by giving them to
+ <seealso marker="#enter_loop/6"><c>enter_loop/6,7</c></seealso>.
+ </p>
+ <p>
+ Actions are executed in the containing list order.
+ </p>
+ <p>
+ Actions that set
+ <seealso marker="#type-transition_option">
+ transition options
+ </seealso>
+ overrides any previous of the same type,
+ so the last in the containing list wins.
+ For example the last
+ <seealso marker="#type-event_timeout">
+ <c>event_timeout()</c>
+ </seealso>
+ overrides any other <c>event_timeout()</c> in the list.
+ </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.
+ </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.
+ </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>
+ </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>.
+ </item>
+ <tag><c>reply_action()</c></tag>
+ <item>Reply to a caller.</item>
+ <tag><c>next_event</c></tag>
+ <item>
+ Store the given <c><anno>EventType</anno></c>
+ and <c><anno>EventContent</anno></c> for insertion after all
+ actions have been executed.
+ </item>
+ <item>
+ <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.
+ </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
+ an event inserted this way from any external event.
+ </p>
+ </item>
+ </taglist>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="reply_action" />
+ <desc>
+ <p>
+ Reply 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
+ <seealso marker="#state_function">state function</seealso>.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <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>
+ </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.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <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>
+ </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.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <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.
+ </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.
+ </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>.
+ </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>.
+ </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.
+ </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>
+ <desc>
+ <p>
+ Makes a synchronous call to the <c>gen_statem</c>
+ <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
+ <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
+ <c><anno>Request</anno></c>.
+ </p>
+ <p>
+ A <c><anno>Reply</anno></c> is generated when a
+ <seealso marker="#state_function">state function</seealso>
+ returns with
+ <c>{reply,From,<anno>Reply</anno>}</c> as one
+ <seealso marker="#type-action"><c>action()</c></seealso>,
+ 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
+ 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
+ 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
+ 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
+ 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>
+ <desc>
+ <p>
+ Sends an asynchronous event to the <c>gen_statem</c>
+ <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
+ <seealso marker="#state_function">state function</seealso> with
+ <seealso marker="#type-event_type"><c>event_type()</c></seealso>
+ <c>cast</c> and event content
+ <c><anno>Msg</anno></c>.
+ </p>
+ </desc>
+ </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>
+ <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>
+ must have been registered.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <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>
+ 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>
+ must have been registered and
+ <c>Actions = <anno>Server_or_Actions</anno></c>.
+ </p>
+ <p>
+ Otherwise the same as
+ <seealso marker="#enter_loop/7"><c>enter_loop/7</c></seealso>
+ with
+ <c>Server = <anno>Server_or_Actions</anno></c> and
+ <c>Actions = []</c>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <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
+ 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>.
+ The user is responsible for any initialization of the process,
+ including registering a name for it.
+ </p>
+ <p>
+ This function is useful when a more complex initialization
+ procedure is needed than
+ the <c>gen_statem</c> behaviour provides.
+ </p>
+ <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>
+ 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>
+ 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>
+ 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>
+ start function, or if it is not registered
+ according to
+ <seealso marker="#type-server_name"><c>server_name()</c></seealso>.
+ </p>
+ </desc>
+ </func>
+
+ </funcs>
+
+
+
+ <section>
+ <title>CALLBACK FUNCTIONS</title>
+ <p>
+ The following functions should be exported from a
+ <c>gen_statem</c> callback module.
+ </p>
+ </section>
+ <funcs>
+
+ <func>
+ <name>Module:init(Args) -> Result</name>
+ <fsummary>Initialize process and internal state</fsummary>
+ <type>
+ <v>Args = term()</v>
+ <v>Result = {CallbackMode,State,Data}</v>
+ <v>&nbsp;| {CallbackMode,State,Data,Actions}</v>
+ <v>&nbsp;| {stop,Reason} | ignore</v>
+ <v>
+ CallbackMode =
+ <seealso marker="#type-callback_mode">callback_mode()</seealso>
+ </v>
+ <v>State = <seealso marker="#type-state">state()</seealso></v>
+ <v>
+ Data = <seealso marker="#type-data">data()</seealso>
+ </v>
+ <v>
+ Actions =
+ [<seealso marker="#type-action">action()</seealso>] |
+ <seealso marker="#type-action">action()</seealso>
+ </v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <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>
+ or
+ <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>
+ <c>Args</c> is the <c>Args</c> argument provided to the start
+ function.
+ </p>
+ <p>
+ If the initialization is successful, the function should
+ 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>.
+ of the <c>gen_statem</c>.
+ <c>State</c> is the initial
+ <seealso marker="#type-state"><c>state()</c></seealso>
+ and <c>Data</c> the initial server
+ <seealso marker="#type-data"><c>data()</c></seealso>.
+ </p>
+ <p>
+ The <seealso marker="#type-action"><c>Actions</c></seealso>
+ are executed when entering the first
+ <seealso marker="#type-state">state</seealso> just as for a
+ <seealso marker="#state_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
+ <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>
+ to return <c>Result</c>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:StateName(EventType, EventContent, Data) ->
+ StateFunctionResult
+ </name>
+ <name>Module:handle_event(EventType, EventContent,
+ State, Data) -> HandleEventResult
+ </name>
+ <fsummary>Handle an event</fsummary>
+ <type>
+ <v>
+ EventType =
+ <seealso marker="#type-event_type">event_type()</seealso>
+ </v>
+ <v>EventContent = term()</v>
+ <v>
+ State =
+ <seealso marker="#type-state">state()</seealso>
+ </v>
+ <v>
+ Data = NewData =
+ <seealso marker="#type-data">data()</seealso>
+ </v>
+ <v>
+ StateFunctionResult =
+ <seealso marker="#type-state_function_result">
+ state_function_result()
+ </seealso>
+ </v>
+ <v>
+ HandleEventResult =
+ <seealso marker="#type-handle_event_result">
+ handle_event_result()
+ </seealso>
+ </v>
+ </type>
+ <desc>
+ <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="#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.
+ </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
+ 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>
+ 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.
+ </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>
+ 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.
+ </p>
+ <p>
+ These functions may use
+ <seealso marker="erts:erlang#throw/1"><c>throw/1</c></seealso>,
+ to return the result.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:terminate(Reason, State, Data) -> Ignored</name>
+ <fsummary>Clean up before termination</fsummary>
+ <type>
+ <v>Reason = normal | shutdown | {shutdown,term()} | term()</v>
+ <v>State = <seealso marker="#type-state">state()</seealso></v>
+ <v>Data = <seealso marker="#type-data">data()</seealso></v>
+ <v>Ignored = term()</v>
+ </type>
+ <desc>
+ <p>
+ This function is called by a <c>gen_statem</c>
+ when it is about to terminate. It should 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>
+ <c>Reason</c> is a term denoting the stop reason and
+ <seealso marker="#type-state"><c>State</c></seealso>
+ is the internal state of the <c>gen_statem</c>.
+ </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
+ <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.
+ </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
+ conditions apply:</p>
+ <list type="bulleted">
+ <item>
+ the <c>gen_statem</c> has been set
+ to trap exit signals, and
+ </item>
+ <item>
+ the shutdown strategy as defined in the supervisor's
+ child specification is an integer timeout value, not
+ <c>brutal_kill</c>.
+ </item>
+ </list>
+ <p>
+ Even if the <c>gen_statem</c> is <em>not</em>
+ part of a supervision tree, this function will be called
+ if it receives an <c>'EXIT'</c> message from its parent.
+ <c>Reason</c> will be the same as
+ in the <c>'EXIT'</c> message.
+ </p>
+ <p>
+ Otherwise, the <c>gen_statem</c> will be 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
+ and an error report is issued using
+ <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>
+ 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>&nbsp;&nbsp;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>,
+ <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>
+ </section>
+</erlref>