If you are new to
This reference manual contains type descriptions generated from
types in the
Two
One for finite-state machines
(
One that allows the state to be any term and that uses one callback function for all states.
The callback model(s) for
A generic state machine server process (
A
gen_statem module Callback module ----------------- --------------- gen_statem:start gen_statem:start_monitor gen_statem:start_link -----> Module:init/1 Server start or code change -----> Module:callback_mode/0 gen_statem:stop -----> Module:terminate/3 gen_statem:call gen_statem:cast gen_statem:send_request erlang:send erlang:'!' -----> Module:StateName/3 Module:handle_event/4 - -----> Module:terminate/3 - -----> Module:code_change/4
Events are of different
If a callback function fails or returns a bad value,
the
The state callback for a specific
When the
When the
When
The
One of the possible transition actions
is to postpone the current event.
Then it is not retried in the current state.
The
The
The
Inserting an event replaces the trick of calling your own
state handling functions that you often would have to
resort to in, for example,
The
If you in
For the details of a state transition, see type
A
Notice that a
Unless otherwise stated, all functions in this module fail if
the specified
The
There is also a server start option
If the
The following example shows a simple pushbutton model
for a toggling pushbutton implemented with
The following is the complete callback module file
-module(pushbutton).
-behaviour(gen_statem).
-export([start/0,push/0,get_count/0,stop/0]).
-export([terminate/3,code_change/4,init/1,callback_mode/0]).
-export([on/3,off/3]).
name() -> pushbutton_statem. % The registered server name
%% 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) ->
{ok,State,Data}.
init([]) ->
%% Set the initial state + data. Data is used only as a counter.
State = off, Data = 0,
{ok,State,Data}.
callback_mode() -> state_functions.
%%% state callback(s)
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}.
The following is a shell session when running it:
1> pushbutton:start(). {ok,<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)
To compare styles, here follows the same example using
callback_mode() -> handle_event_function.
%%% state callback(s)
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}.
Name specification to use when starting
a
Server specification to use when addressing
a
It can be:
The
The
The
The
Options that can be used when starting
a
Return value from the
Return value from the
Options that can be used when starting
a
For every entry in
Destination to use when replying through, for example, the
A handle that associates a reply to the corresponding request.
If the
If the
A term in which the state machine implementation
is to store any server data it needs. The difference between
this and the
There are 3 categories of events:
External events are of 3 types:
There are 3 types of time-out events that the state machine
can generate for itself with the corresponding
Any event's content can be any term.
See
This is the return type from
The callback mode is selected
with the return value from
The state must be of type
The state can be any term and the callback function
The function
Whether the state machine should use state enter calls
or not is selected when starting the
If
If
If
Note that a state enter call will be done
right before entering the initial state even though this
actually is not a state change.
In this case
Transition options can be set by
All returned
If
If
If
If this is a state change, the queue of incoming events is reset to start with the oldest postponed.
All events stored with
Time-out timers
Any event cancels an
A state change cancels a
If there are enqueued events the
Otherwise the
If
If
If there are enqueued events to process
when hibrnation is requested,
this is optimized by not hibernating but instead calling
Starts a timer set by
Any event that arrives cancels this time-out. Note that a retried or inserted event counts as arrived. So does a state time-out zero event, if it was generated before this time-out is requested.
If
If
Note that it is not possible nor needed to cancel this time-out, as it is cancelled automatically by any other event.
Starts a timer set by
If
If
Setting a timer with the same
Starts a timer set by
If
If
Setting this timer while it is running will restart it with
the new time-out value. Therefore it is possible to cancel
this time-out by setting it to
If
These transition actions can be invoked by
returning them from the
Actions are executed in the containing list order.
Actions that set
Sets the
This action does not set any
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
An event of type
Changes the callback module to
The
Changing the callback module does not affect the
state transition in any way,
it only changes which module that handles the events.
Be aware that all relevant callback functions in
Pushes the current callback module
to the top of an internal stack of callback modules
and changes the callback module to
These transition actions can be invoked by
returning them from the
Actions are executed in the containing list order.
Actions that set
Sets the
These transition actions can be invoked by
returning them from the
These time-out actions sets time-out
Short for
Sets the
Sets the
Sets the
This is a shorter and clearer form of
Updates a time-out with a new
If no time-out of the same type is active instead
insert the time-out event just like when starting
a time-out with relative
This transition action can be invoked by
returning it from the
It does not set any
Note that using this action from
For a succesful initialization,
The
For an unsuccesful initialization,
The
The
The same as
The same as
If the
The same as
Terminates the
Sends all
All these terms are tuples or atoms and this property
will hold in any future version of
An opaque request identifier. See
An opaque collection of request identifiers
(
Used to set a time limit on how long to wait for a response using
either
Timeout relative to current time in milliseconds.
Infinite timeout. That is, the operation will never time out.
An absolute
A map that describes the
New associations may be added to the status map without prior notice.
Makes a synchronous call to the
A
For
If you combine catching exceptions from this function
with
The call can also fail, for example, if the
When this call fails it
Sends an asynchronous event to the
Check if
The return value
The function returns an error if the
Check if
The
Compared to
If
If
The same as
If
Otherwise the same as
Makes the calling process become a
This function is useful when a more complex initialization
procedure is needed than
the
If
The function fails if the calling process was not started by a
The same as calling
Receive a response corresponding to the request identifier
The return value
The function returns an error if the
The difference between
Receive a response corresponding to a request identifier saved
in
The
Compared to
If
The difference between
If
This function can be used by a
A reply sent with this function is not visible
in
Saves
Returns a new empty request identifier collection. A request identifier collection can be utilized in order the handle multiple outstanding requests.
Request identifiers of requests made by
Returns the amount of request identifiers saved in
Returns a list of
Sends an asynchronous
The call
The
A
Sends an asynchronous
The same as calling
Creates a standalone
For a description of arguments and return values, see
Creates a
The
If option
If option
If option
If option
Using spawn option
If the
If
Creates a standalone
For a description of arguments and return values, see
The same as
Orders the
This function returns
If the process does not exist, the call exits
the calling process with reason
The same as calling
Wait for a response corresponding to the request identifier
The return value
The function returns an error if the
The difference between
Wait for a response corresponding to a request identifier saved
in
The
Compared to
If
The difference between
If
The following functions are to be exported from a
This function is called by a
Server start happens either when
The
If this function's body does not return an inline constant value the callback module is doing something strange.
This callback is optional, so callback modules need not export it.
If a release upgrade/downgrade with
This function is called by a
For an upgrade,
If successful, the function must return the updated
internal state in an
If the function returns a failure
Also note when upgrading a
If the server changes callback module using any of the actions
In the supervisor
Whenever a
Note that if the
-spec init(_) -> no_return(). init(Args) -> erlang:error(not_implemented, [Args]).
This callback is optional, so a callback module does not need
to export it. The
If this callback is exported but fails,
to hide possibly sensitive data,
the default function will instead return
This function is called by a
The
This function is useful for changing the form and
appearance of the
One use case for this function is to return compact alternative state representations to avoid having large state terms printed in log files. Another is to hide sensitive data from being written to the error log.
Example:
maps:map(
fun(state,State) ->
maps:remove(private_key, State);
(message,{password, _Pass}) ->
{password, removed};
(_,Value) ->
Value
end, Status).
]]>
This callback is deprecated, in new code use
This callback is optional, so a callback module does not need
to export it. The
If this callback is exported but fails,
to hide possibly sensitive data,
the default function will instead return
This function is called by a
This function is useful for changing the form and
appearance of the
The function is to return
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.
Whenever a
If
If this function returns with a next state that
does not match equal (
The only difference between
For options that can be set and actions that can be done
by
When the
Note the fact that you can use
This callback is optional, so callback modules need not
export it. The
This function is called by a
If the
The
The shutdown strategy as defined in the supervisor's
child specification is an integer time-out value, not
Even if the
Otherwise, the
Notice that for any other reason than
When the