Gen StateM
The
gen_statembehaviour is based on the Mealy State Machine. In versions before OTP 20, another behaviour called Gen FSM implemented a Moore State Machine. The Mealy machine implementation improved performance for all OTP libraries.This behavior is built on the server behavior (
gen_server) (…), also adding state management at the behavior level. The difference between the server and the state machine is that an event received by a server is handled in only one dimension, the implemented code and the only existing state data. In the state machine, the code that handles each request, and each event, depends on the internal state of the state machine.
Concepts
Event Handlers
handle_event(Type, Content, State, Data) ->
{next_state, NextState, NewData, Actions}
| {stop, Reason, NewData}.
| {keep_state, ...}
| {keep_state_and_data, ...}
| {repeat_state, ...}
| {stop_and_reply, ...}
where
Type :: cast | {call, From} | info | timeout | ...
and you take Actions to mean "a list of Action" with
the following signanture:
Action ::
% enter_action()
%% reply_action()
{reply, From :: from(), Reply :: term()}
%% timeout_action()
| {Time :: event_timeout()}
| {timeout, Time :: event_timeout(), EventContent :: event_content()}
| {timeout, Time :: event_timeout(), EventContent :: event_content(), Options :: timeout_options() }
| (...)
%% Others kinds of enter_action()
| hibernate
| {hibernate, Hibernate :: hibernate()}
% Other kinds of Actions
| postpone
| {postpone, Postpone :: postpone()}
| {next_event, EventType :: event_type(), EventContent :: event_content() }
| {change_callback_module, NewModule :: module(), EventContent :: event_content() }
| {push_callback_module, NewModule :: module()}
| pop_callback_module
| ...
Event Types
- External
-type external_event_type() :: {call, From :: from()} | cast | info.
| Module | Callback |
|---|---|
gen_statem:cast(Server, Msg) |
Mod:StateName(cast, Msg, Data) |
gen_statem:call(Server, Req) |
Mod:StateName({call, From}, Req, Data) |
Server ! Msg |
Mod:StateName(info, Msg, Data) |
- Timeout
-type timeout_event_type() :: timeout | {timeout, Name :: term()} | state_timeout.
| Message | Callback |
|---|---|
{timeout, Time, Msg} |
Mod:StateName(timeout, Msg, Data) |
{{timeout, Name}, Msg, Data} |
Mod:StateName({timeout, Name}, Msg, Data) |
{state_timeout, Msg, Data} |
Mod:StateName(state_timeout, Msg, Data) |
- Internal
internal events can only be generated by the state machine itself through the transition action
next_event.
| Message | Callback |
|---|---|
{next_event, internal, Msg} |
Mod:StateName(internal, Msg, Data) |