From 17405463ba134e71ff09e8d2921de9aa931805ee Mon Sep 17 00:00:00 2001
From: Raimo Niskanen
- In mode
- In mode
handle_event(EventType, EventContent, State, Data) -> .. code for actions here ... - {next_state, State', Data'}+ {next_state, NewState, NewData}
Both these modes allow other return tuples; see
-
@@ -291,9 +290,7 @@ start_link(Code) -> ]]>
The fourth argument,
Function
-
Function
-
The function notifying the code lock about a button event is
implemented using
-
@@ -528,9 +509,7 @@ handle_event({call,From}, code_length, #{code := Code} = Data) ->
]]>
This example uses
-
If mode
strategy must be a time-out value and the gen_statem must
in function init/1 set itself to trap exit signals
by calling
-
- process_flag(trap_exit, true)
- .
- When ordered to shut down, the gen_statem then calls
- callback function terminate(shutdown, State, Data) :
+ process_flag(trap_exit, true) :
@@ -616,6 +589,10 @@ init(Args) ->
do_lock(),
...
]]>
+
+ When ordered to shut down, the gen_statem then calls
+ callback function terminate(shutdown, State, Data) .
+
In the following example, function terminate/3
locks the door if it is open, so we do not accidentally leave the door
@@ -633,9 +610,7 @@ terminate(_Reason, State, _Data) ->
If the gen_statem is not part of a supervision tree,
it can be stopped using
-
- gen_statem:stop
- ,
+ gen_statem:stop ,
preferably through an API function:
Actions
In the first sections actions were mentioned as a part of
- the general state machine model. These actions
+ the general state machine model. These general actions
are implemented with the code that callback module
gen_statem executes in an event-handling
callback function before returning
@@ -671,17 +646,11 @@ stop() ->
that a callback function can order the gen_statem
engine to do after the callback function return.
These are ordered by returning a list of
-
- actions
-
+ actions
in the
-
- return tuple
-
+ return tuple
from the
-
- callback function
- .
+ callback function .
These state transition actions affect the gen_statem
engine itself and can do the following:
@@ -697,9 +666,7 @@ stop() ->
and replying to a caller.
An example of event postponing is included later in this chapter.
For details, see the
-
- gen_statem(3)
-
+ gen_statem(3)
manual page.
You can, for example, reply to many callers
and generate multiple next events to handle.
@@ -712,9 +679,7 @@ stop() ->
Event Types
The previous sections mentioned a few
-
- event types
- .
+ event types .
Events of all types are handled in the same callback function,
for a given state, and the function gets
EventType and EventContent as arguments.
@@ -727,22 +692,16 @@ stop() ->
cast
-
Generated by
-
- gen_statem:cast .
-
+ gen_statem:cast .
{call,From}
-
Generated by
-
- gen_statem:call
- ,
+ gen_statem:call ,
where From is the reply address to use
when replying either through the state transition action
{reply,From,Msg} or by calling
-
- gen_statem:reply
- .
+ gen_statem:reply .
info
-
@@ -759,7 +718,7 @@ stop() ->
-
Generated by state transition action
{next_event,internal,EventContent} .
- All event types above can be generated using
+ All event types above can also be generated using
{next_event,EventType,EventContent} .
@@ -780,9 +739,7 @@ stop() ->
or you want to start a timer in one state and respond
to the time-out in another. This can be accomplished
with a regular Erlang timer:
-
- erlang:start_timer .
-
+ erlang:start_timer .
For the example so far in this chapter: using the
@@ -818,9 +775,7 @@ open(cast, {button,_}, Data) ->
]]>
If you need to cancel a timer because of some other event, you can use
-
- erlang:cancel_timer(Tref)
- .
+ erlang:cancel_timer(Tref) .
Notice that a time-out message cannot arrive after this,
unless you have postponed it (see the next section) before,
so ensure that you do not accidentally postpone such messages.
@@ -844,9 +799,7 @@ open(cast, {button,_}, Data) ->
Postponing is ordered by the state transition
-
- action
-
+ action
postpone .
@@ -861,7 +814,7 @@ open(cast, {button,_}, Data) ->
...
]]>
- A postponed event is only retried after a state change
+ The fact that a postponed event is only retried after a state change
translates into a requirement on the event and state space.
If you have a choice between storing a state data item
in the
The state transition
-
You can generate events of any existing
-
This section describes what to change in the example
to use one
To avoid this, you can format the internal state
that gets in the error log and gets returned from
-
- sys:get_status/1,2
-
+ sys:get_status/1,2
by implementing function
-
- Module:format_status/2
- ,
+ Module:format_status/2 ,
for example like this:
]]>
It is not mandatory to implement a
-
- Module:format_status/2
-
+ Module:format_status/2
function. If you do not, a default implementation is used that
does the same as this example function without filtering
the Data term, that is, StateData = {State,Data} .
@@ -1274,13 +1215,9 @@ format_status(Opt, [_PDict,State,Data]) ->
Complex State
The callback mode
-
- handle_event_function
-
+ handle_event_function
enables using a non-atom state as described in section
-
- Callback Modes
- ,
+ Callback Modes ,
for example, a complex state term like a tuple.
@@ -1308,8 +1245,7 @@ format_status(Opt, [_PDict,State,Data]) ->
So we make the button/1 function synchronous
by using
-
- gen_statem:call
+ gen_statem:call
and still postpone its events in the open state.
Then a call to button/1 during the open
state does not return until the state transits to locked ,
@@ -1462,16 +1398,12 @@ format_status(Opt, [_PDict,State,Data]) ->
and the amount of heap memory all these servers need
is a problem, then the memory footprint of a server
can be mimimized by hibernating it through
-
- proc_lib:hibernate/3 .
-
+ proc_lib:hibernate/3 .
It is rather costly to hibernate a process; see
-
- erlang:hibernate/3
- .
+ erlang:hibernate/3 .
It is not something you want to do after every event.
@@ -1495,9 +1427,7 @@ handle_event(
]]>
The
-