From f986565050ac30075ef3c0a451bf6dad91c7c446 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 13 Sep 2016 11:15:32 +0200 Subject: Implement call/3 dirty_timeout --- lib/stdlib/doc/src/gen_statem.xml | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'lib/stdlib/doc') diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index 3322571b2c..17f1526a21 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -919,18 +919,40 @@ handle_event(_, _, State, Data) ->

- For Timeout =/= infinity, + For Timeout < infinity, to avoid getting a late reply in the caller's - inbox, this function spawns a proxy process that + inbox if the caller should catch exceptions, + 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 - Timeout =:= infinity. + Timeout == infinity.

- The call can fail, for example, if the gen_statem dies - before or during this function call. + Timeout can also be a tuple + {clean_timeout,T} or + {dirty_timeout,T}, where + T is the timeout time. + {clean_timeout,T} works like + just T described in the note above + and uses a proxy process for T < infinity, + while {dirty_timeout,T} + bypasses the proxy process which is more lightweight. +

+ +

+ If you combine catching exceptions from this function + with {dirty_timeout,T} + to avoid that the calling process dies when the call + times out, you will have to be prepared to handle + a late reply. + So why not just allow the calling process to die? +

+
+

+ The call can also fail, for example, if the gen_statem + dies before or during this function call.

-- cgit v1.2.3 From 6ee0aefd8a0ea9c165211c42d5244182b5aa9210 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 13 Sep 2016 14:00:04 +0200 Subject: Implement state entry events --- lib/stdlib/doc/src/gen_statem.xml | 82 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 6 deletions(-) (limited to 'lib/stdlib/doc') diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index 17f1526a21..a4c5438a08 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -70,6 +70,7 @@ The state can be any term. Events can be postponed. Events can be self-generated. + Automatic state entry events can be generated. A reply can be sent from a later state. There can be multiple sys traceable replies. @@ -193,6 +194,12 @@ erlang:'!' -----> Module:StateName/3 gen_fsm to force processing an inserted event before others.

+

+ The gen_statem engine can automatically insert + a special event whenever a new state is entered; see + state_entry_mode(). + This makes it easy to handle code common to all state entries. +

If you in gen_statem, for example, postpone an event in one state and then call another state function @@ -515,7 +522,7 @@ handle_event(_, _, State, Data) -> Type info originates from regular process messages sent to the gen_statem. Also, the state machine implementation can generate events of types - timeout and internal to itself. + timeout, enter and internal to itself.

@@ -550,6 +557,34 @@ handle_event(_, _, State, Data) -> + + + +

+ The state entry mode is selected when starting the + gen_statem and after code change + using the return value from + Module:callback_mode/0. +

+

+ If + Module:callback_mode/0 + returns a list containing state_entry_events, + the gen_statem engine will, at every state change, + insert an event of type + enter + with content OldState. This event will be inserted + before all other events such as those generated by + action() + next_event. +

+

+ If + Module:callback_mode/0 + does not return such a list, no state entry events are inserted. +

+
+
@@ -590,6 +625,16 @@ handle_event(_, _, State, Data) -> all other events.

+ +

+ If the state changes or is the initial state, and the + state entry mode + is state_entry_events, an event of type + enter + with content OldState is inserted + to be processed before all other events including those above. +

+

If an @@ -1288,7 +1333,9 @@ handle_event(_, _, State, Data) -> CallbackMode = - callback_mode() + callback_mode() | + [ callback_mode() + | state_entry_events ] @@ -1313,12 +1360,35 @@ handle_event(_, _, State, Data) -> Module:code_change/4 returns.

+

+ The CallbackMode is either just + callback_mode() + or a list containing + callback_mode() + and possibly the atom + state_entry_events. +

+

+ If the atom state_entry_events is present in the list, + the gen_statem engine will, at every state change, + insert an event of type + enter + with content OldState. This event will be inserted + before all other events such as those generated by + action() + next_event. +

+

+ No state entry event will be inserted after a + Module:code_change/4 + since transforming the state to a newer version is regarded + as staying in the same state even if the newer version state + should have a different name. +

- If this function's body does not consist of solely one of two - possible - atoms - the callback module is doing something strange. + If this function's body does not return an inline constant + value the callback module is doing something strange.

-- cgit v1.2.3 From 4ebdabdca2c964887115f21405993f3916843d10 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 16 Sep 2016 10:15:22 +0200 Subject: Improve docs --- lib/stdlib/doc/src/gen_statem.xml | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'lib/stdlib/doc') diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index a4c5438a08..944e9ab13b 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -583,6 +583,20 @@ handle_event(_, _, State, Data) -> Module:callback_mode/0 does not return such a list, no state entry events are inserted.

+

+ No state entry event will be inserted after a + Module:code_change/4 + since transforming the state to a newer version is regarded + as staying in the same state even if the newer version state + should have a different name. +

+

+ Note that a state entry event will be inserted + when entering the initial state even though this formally + is not a state change. In this case OldState + will be the same as State, which can not happen + for an actual state change. +

@@ -1335,7 +1349,7 @@ handle_event(_, _, State, Data) -> CallbackMode = callback_mode() | [ callback_mode() - | state_entry_events ] + | state_entry_events ] @@ -1368,23 +1382,6 @@ handle_event(_, _, State, Data) -> and possibly the atom state_entry_events.

-

- If the atom state_entry_events is present in the list, - the gen_statem engine will, at every state change, - insert an event of type - enter - with content OldState. This event will be inserted - before all other events such as those generated by - action() - next_event. -

-

- No state entry event will be inserted after a - Module:code_change/4 - since transforming the state to a newer version is regarded - as staying in the same state even if the newer version state - should have a different name. -

If this function's body does not return an inline constant -- cgit v1.2.3 From 04d40c5cd18aca449606c19608e8044f593ee99e Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 22 Sep 2016 17:40:47 +0200 Subject: Change state entry events into state enter calls --- lib/stdlib/doc/src/gen_statem.xml | 305 ++++++++++++++++++++++++++++---------- 1 file changed, 226 insertions(+), 79 deletions(-) (limited to 'lib/stdlib/doc') diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index 944e9ab13b..aa34f53d29 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -54,7 +54,8 @@

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. + 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. @@ -70,7 +71,7 @@ The state can be any term. Events can be postponed. Events can be self-generated. - Automatic state entry events can be generated. + Automatic state enter code can be called. A reply can be sent from a later state. There can be multiple sys traceable replies. @@ -195,10 +196,14 @@ erlang:'!' -----> Module:StateName/3 to force processing an inserted event before others.

- The gen_statem engine can automatically insert - a special event whenever a new state is entered; see - state_entry_mode(). - This makes it easy to handle code common to all state entries. + The gen_statem engine can automatically + make a specialized call to the + state function + whenever a new state is entered; see + state_enter(). + This is for writing code common to all state entries. + Another way to do it is to insert events at state transitions, + but you have to do so everywhere it is needed.

If you in gen_statem, for example, postpone @@ -526,6 +531,20 @@ handle_event(_, _, State, Data) ->

+ + + +

+ This is the return type from + Module:callback_mode/0 + and selects + callback mode + and whether to do + state enter calls, + or not. +

+
+
@@ -558,44 +577,48 @@ handle_event(_, _, State, Data) -> - +

- The state entry mode is selected when starting the - gen_statem and after code change - using the return value from + If the state machine should use state enter calls + is selected when starting the gen_statem + and after code change using the return value from Module:callback_mode/0.

If Module:callback_mode/0 - returns a list containing state_entry_events, + returns a list containing state_enter, the gen_statem engine will, at every state change, - insert an event of type - enter - with content OldState. This event will be inserted - before all other events such as those generated by - action() - next_event. + call the + state function + with arguments (enter, OldState, Data). + This may look like an event but is really a call + performed after the previous state function returned + and before any event is delivered to the new state function. + See + Module:StateName/3 + and + Module:handle_event/4.

If Module:callback_mode/0 - does not return such a list, no state entry events are inserted. + does not return such a list, no state enter calls are done.

- No state entry event will be inserted after a + If Module:code_change/4 - since transforming the state to a newer version is regarded - as staying in the same state even if the newer version state - should have a different name. + should transform the state to a state with a different + name it is still regarded as the same state so this + does not cause a state enter call.

- Note that a state entry event will be inserted - when entering the initial state even though this formally - is not a state change. In this case OldState - will be the same as State, which can not happen - for an actual state change. + Note that a state enter call will be done + right before entering the initial state even though this + formally is not a state change. + In this case OldState will be the same as State, + which can not happen for a subsequent state change.

@@ -605,8 +628,7 @@ handle_event(_, _, State, Data) ->

Transition options can be set by actions - and they modify the following in how - the state transition is done: + and they modify how the state transition is done:

@@ -636,17 +658,22 @@ handle_event(_, _, State, Data) -> action() next_event are inserted in the queue to be processed before - all other events. + other events.

- If the state changes or is the initial state, and the - state entry mode - is state_entry_events, an event of type - enter - with content OldState is inserted - to be processed before all other events including those above. + If the state changes or is the initial state, and + state enter calls + are used, the gen_statem calls + the new state function with arguments + (enter, OldState, Data). + If this call returns any + actions + that sets transition options + they are merged with the current + That is: hibernate and timeout overrides + the current and reply sends a reply.

@@ -656,8 +683,9 @@ handle_event(_, _, State, Data) -> is set through action() timeout, - an event timer can be started or a time-out zero event - can be enqueued. + an event timer is started if the value is less than + infinity or a time-out zero event + is enqueued if the value is zero.

@@ -732,7 +760,7 @@ handle_event(_, _, State, Data) -> is processed before any not yet received external event.

- Notice that it is not possible or needed to cancel this time-out, + Note that it is not possible or needed to cancel this time-out, as it is cancelled automatically by any other event.

@@ -743,7 +771,10 @@ handle_event(_, _, State, Data) ->

These state transition actions can be invoked by returning them from the - state function, from + state function + when it is called with an + event, + from Module:init/1 or by giving them to enter_loop/5,6. @@ -757,8 +788,8 @@ handle_event(_, _, State, Data) -> override any previous of the same type, so the last in the containing list wins. For example, the last - event_timeout() - overrides any other event_timeout() in the list. + postpone() + overrides any previous postpone() in the list.

postpone @@ -775,6 +806,53 @@ handle_event(_, _, State, Data) -> as there is no event to postpone in those cases.

+ next_event + +

+ Stores the specified EventType + and EventContent for insertion after all + actions have been executed. +

+

+ 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 next_event in the containing + list becomes the first to process. +

+

+ An event of type + internal + is to be used when you want to reliably distinguish + an event inserted this way from any external event. +

+
+ + + + + + +

+ These state transition actions can be invoked by + returning them from the + state function, from + Module:init/1 + or by giving them to + enter_loop/5,6. +

+

+ Actions are executed in the containing list order. +

+

+ Actions that set + transition options + override any previous of the same type, + so the last in the containing list wins. + For example, the last + event_timeout() + overrides any previous event_timeout() in the list. +

+ hibernate

@@ -805,32 +883,6 @@ handle_event(_, _, State, Data) -> to Time with EventContent.

- reply_action() - -

- Replies to a caller. -

-
- next_event - -

- Stores the specified EventType - and EventContent for insertion after all - actions have been executed. -

-

- 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 next_event in the containing - list becomes the first to process. -

-

- An event of type - internal - is to be used when you want to reliably distinguish - an event inserted this way from any external event. -

-
@@ -838,13 +890,31 @@ handle_event(_, _, State, Data) ->

- Replies to a caller waiting for a reply in + This state transition action can be invoked by + returning it from the + state function, from + Module:init/1 + or by giving it to + enter_loop/5,6. +

+

+ It replies to a caller waiting for a reply in call/2. From must be the term from argument {call,From} - to the + in a call to a state function.

+

+ Note that using this action from + Module:init/1 + or + enter_loop/5,6 + would be weird on the border of whichcraft + since there has been no earlier call to a + state function + in this server. +

@@ -868,6 +938,27 @@ handle_event(_, _, State, Data) ->

+ + + + + next_state + +

+ The gen_statem does a state transition to + NextStateName + (which can be the same as the current state), + sets NewData, + and executes all Actions. +

+
+
+

+ All these terms are tuples or atoms and this property + will hold in any future version of gen_statem. +

+
+
@@ -889,6 +980,27 @@ handle_event(_, _, State, Data) ->

+ + + + + next_state + +

+ The gen_statem does a state transition to + NextState + (which can be the same as the current state), + sets NewData, + and executes all Actions. +

+
+
+

+ All these terms are tuples or atoms and this property + will hold in any future version of gen_statem. +

+
+
@@ -1148,10 +1260,11 @@ handle_event(_, _, State, Data) -> {call,From} to the state function. - From and Reply - can also be specified using a - reply_action() - and multiple replies with a list of them. + A reply or multiple replies canalso be sent + using one or several + reply_action()s + from a + state function.

@@ -1362,7 +1475,8 @@ handle_event(_, _, State, Data) -> once after server start and after code change, but before the first state function - is called. More occasions may be added in future versions + in the current code version is called. + More occasions may be added in future versions of gen_statem.

@@ -1380,7 +1494,7 @@ handle_event(_, _, State, Data) -> or a list containing callback_mode() and possibly the atom - state_entry_events. + state_enter.

@@ -1601,7 +1715,8 @@ handle_event(_, _, State, Data) ->

The function is to return Status, a term that - changes the details of the current state and status of + contains the appropriate details + of the current state and status of the gen_statem. There are no restrictions on the form Status can take, but for the sys:get_status/1,2 @@ -1625,11 +1740,17 @@ handle_event(_, _, State, Data) -> + Module:StateName(enter, OldState, Data) -> + StateFunctionEnterResult + Module:StateName(EventType, EventContent, Data) -> StateFunctionResult - Module:handle_event(EventType, EventContent, - State, Data) -> HandleEventResult + Module:handle_event(enter, OldState, State, Data) -> + HandleEventResult + + Module:handle_event(EventType, EventContent, State, Data) -> + HandleEventResult Handle an event. @@ -1650,10 +1771,18 @@ handle_event(_, _, State, Data) -> StateFunctionResult = state_function_result() + + StateFunctionEnterResult = + state_function_enter_result() + HandleEventResult = handle_event_result() + + HandleEventEnterResult = + handle_event_enter_result() +

@@ -1694,6 +1823,24 @@ handle_event(_, _, State, Data) -> by gen_statem after returning from this function, see action().

+

+ When the gen_statem runs with + state enter calls, + these functions are also called with arguments + (enter, OldState, ...) whenever the state changes. + In this case there are some restrictions on the + actions + that may be returned: + postpone() + and + {next_event,_,_} + are not allowed. + You may also not change states from this call. + Should you return {next_state,NextState, ...} + with NextState =/= State the gen_statem crashes. + You are advised to use {keep_state,...} or + keep_state_and_data. +

Note the fact that you can use throw -- cgit v1.2.3 From 800265f49f912dcf66846b13aa8032bf2f380caf Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 30 Sep 2016 11:17:22 +0200 Subject: Improve docs and types --- lib/stdlib/doc/src/gen_statem.xml | 77 +++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 15 deletions(-) (limited to 'lib/stdlib/doc') diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index aa34f53d29..bba2de5e77 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -674,6 +674,9 @@ handle_event(_, _, State, Data) -> they are merged with the current That is: hibernate and timeout overrides the current and reply sends a reply. + This has the same effect as if you would have appended + the actions from this state enter call to the actions + returned by the state function that changed states.

@@ -1002,28 +1005,42 @@ handle_event(_, _, State, Data) ->
- + - stop + keep_state

- Terminates the gen_statem by calling - Module:terminate/3 - with Reason and - NewData, if specified. + The gen_statem keeps the current state, or + does a state transition to the current state if you like, + sets NewData, + and executes all Actions. + This is the same as + {next_state,CurrentState,NewData,Actions}.

- stop_and_reply + keep_state_and_data

- Sends all Replies, - then terminates the gen_statem by calling - Module:terminate/3 - with Reason and - NewData, if specified. + The gen_statem keeps the current state or + does a state transition to the current state if you like, + keeps the current server data, + and executes all Actions. + This is the same as + {next_state,CurrentState,CurrentData,Actions}.

+
+

+ All these terms are tuples or atoms and this property + will hold in any future version of gen_statem. +

+
+
+ + + + keep_state

@@ -1053,6 +1070,36 @@ handle_event(_, _, State, Data) ->

+ + + + + stop + +

+ Terminates the gen_statem by calling + Module:terminate/3 + with Reason and + NewData, if specified. +

+
+ stop_and_reply + +

+ Sends all Replies, + then terminates the gen_statem by calling + Module:terminate/3 + with Reason and + NewData, if specified. +

+
+
+

+ All these terms are tuples or atoms and this property + will hold in any future version of gen_statem. +

+
+
@@ -1462,7 +1509,7 @@ handle_event(_, _, State, Data) -> CallbackMode = callback_mode() | [ callback_mode() - | state_entry_events ] + | state_enter() ] @@ -1490,9 +1537,9 @@ handle_event(_, _, State, Data) ->

The CallbackMode is either just - callback_mode() + callback_mode() or a list containing - callback_mode() + callback_mode() and possibly the atom state_enter.

-- cgit v1.2.3 From 77e175589b0ee3c1a4c94aef3cdcdf54cd84c53c Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 30 Sep 2016 18:00:38 +0200 Subject: Implement state timeouts --- lib/stdlib/doc/src/gen_statem.xml | 105 ++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 32 deletions(-) (limited to 'lib/stdlib/doc') diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index bba2de5e77..c0631c8448 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -527,7 +527,8 @@ handle_event(_, _, State, Data) -> Type info originates from regular process messages sent to the gen_statem. Also, the state machine implementation can generate events of types - timeout, enter and internal to itself. + timeout, state_timeout, enter, + and internal to itself.

@@ -657,8 +658,7 @@ handle_event(_, _, State, Data) -> All events stored with action() next_event - are inserted in the queue to be processed before - other events. + are inserted to be processed before the other queued events.

@@ -668,35 +668,36 @@ handle_event(_, _, State, Data) -> are used, the gen_statem calls the new state function with arguments (enter, OldState, Data). - If this call returns any + Any actions - that sets transition options - they are merged with the current - That is: hibernate and timeout overrides - the current and reply sends a reply. - This has the same effect as if you would have appended - the actions from this state enter call to the actions + returned from this call are handled as if they were + appended to the actions returned by the state function that changed states.

- If an - event_timeout() - is set through - action() - timeout, - an event timer is started if the value is less than - infinity or a time-out zero event - is enqueued if the value is zero. + If there are enqueued events the (possibly new) + state function + is called with the oldest enqueued event, + and we start again from the top of this list.

- The (possibly new) + Timeout timers + state_timeout() + and + event_timeout() + are handled. This may lead to a time-out zero event + being generated to the state function - is called with the oldest enqueued event if there is any, - otherwise the gen_statem goes into receive + and we start again from the top of this list. +

+
+ +

+ Otherwise the gen_statem goes into receive or hibernation (if hibernate() @@ -704,8 +705,11 @@ handle_event(_, _, State, Data) -> to wait for the next message. In hibernation the next non-system event awakens the gen_statem, or rather the next incoming message awakens the gen_statem, - but if it is a system event - it goes right back into hibernation. + but if it is a system event it goes right back into hibernation. + When a new message arrives the + state function + is called with the corresponding event, + and we start again from the top of this list.

@@ -747,20 +751,20 @@ handle_event(_, _, State, Data) -> event_type() timeout 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. + event arrives or has arrived + in which case this time-out is cancelled. + Note that a retried, inserted or state time-out zero + events counts as arrived.

If the value is infinity, no timer is started, as - it never triggers anyway. + it never would trigger anyway.

- If the value is 0, 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 0 event - is processed before any not yet received external event. + If the value is 0 no timer is actually started, + instead the the time-out event is enqueued to ensure + that it gets processed before any not yet + received external event.

Note that it is not possible or needed to cancel this time-out, @@ -768,6 +772,34 @@ handle_event(_, _, State, Data) ->

+ + + +

+ Generates an event of + event_type() + state_timeout + after this time (in milliseconds) unless the gen_statem + changes states (NewState =/= OldState) + which case this time-out is cancelled. +

+

+ If the value is infinity, no timer is started, as + it never would trigger anyway. +

+

+ If the value is 0 no timer is actually started, + instead the the time-out event is enqueued to ensure + that it gets processed before any not yet + received external event. +

+

+ Setting this timer while it is running will restart it with + the new time-out value. Therefore it is possible to cancel + this timeout by setting it to infinity. +

+
+
@@ -886,6 +918,15 @@ handle_event(_, _, State, Data) -> to Time with EventContent.

+ state_timeout + +

+ Sets the + transition_option() + state_timeout() + to Time with EventContent. +

+
-- cgit v1.2.3 From f4de3f5887be010db178a178e1f20027f3e5d22b Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 12 Oct 2016 17:49:26 +0200 Subject: Use parameterized types --- lib/stdlib/doc/src/gen_statem.xml | 216 ++++++++++++++------------------------ 1 file changed, 77 insertions(+), 139 deletions(-) (limited to 'lib/stdlib/doc') diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index c0631c8448..64267c2af5 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -127,9 +127,9 @@ erlang:'!' -----> Module:StateName/3 is not regarded as an error but as a valid return from all callback functions.

- +

- The "state function" for a specific + The "state callback" for a specific state in a gen_statem is the callback function that is called for all events in this state. It is selected depending on which @@ -141,7 +141,7 @@ erlang:'!' -----> Module:StateName/3 When the callback mode is state_functions, the state must be an atom and - is used as the state function name; see + is used as the state callback name; see Module:StateName/3. This gathers all code for a specific state in one function as the gen_statem engine @@ -154,7 +154,7 @@ erlang:'!' -----> Module:StateName/3 When the callback mode is handle_event_function, the state can be any term - and the state function name is + and the state callback name is Module:handle_event/4. This makes it easy to branch depending on state or event as you desire. Be careful about which events you handle in which @@ -164,8 +164,8 @@ erlang:'!' -----> Module:StateName/3

The gen_statem enqueues incoming events in order of arrival and presents these to the - state function - in that order. The state function can postpone an event + state callback + in that order. The state callback can postpone an event so it is not retried in the current state. After a state change the queue restarts with the postponed events.

@@ -177,12 +177,12 @@ erlang:'!' -----> Module:StateName/3 to entering a new receive statement.

- The state function + The state callback can insert events using the action() next_event and such an event is inserted as the next to present - to the state function. That is, as if it is + to the state callback. That is, as if it is the oldest incoming event. A dedicated event_type() internal can be used for such events making them impossible @@ -198,7 +198,7 @@ erlang:'!' -----> Module:StateName/3

The gen_statem engine can automatically make a specialized call to the - state function + state callback whenever a new state is entered; see state_enter(). This is for writing code common to all state entries. @@ -207,7 +207,7 @@ erlang:'!' -----> Module:StateName/3

If you in gen_statem, for example, postpone - an event in one state and then call another state function + an event in one state and then call another state callback of yours, you have not changed states and hence the postponed event is not retried, which is logical but can be confusing.

@@ -236,7 +236,7 @@ erlang:'!' -----> Module:StateName/3 The gen_statem process can go into hibernation; see proc_lib:hibernate/3. It is done when a - state function or + state callback or Module:init/1 specifies hibernate in the returned Actions @@ -294,7 +294,7 @@ init([]) -> {ok,State,Data}. callback_mode() -> state_functions. -%%% State function(s) +%%% state callback(s) off({call,From}, push, Data) -> %% Go to 'on', increment count and reply @@ -348,7 +348,7 @@ ok callback_mode() -> handle_event_function. -%%% State function(s) +%%% state callback(s) handle_event({call,From}, push, off, Data) -> %% Go to 'on', increment count and reply @@ -482,6 +482,10 @@ handle_event(_, _, State, Data) ->

+ If the + callback mode + is handle_event_function, + the state can be any term. After a state change (NextState =/= State), all postponed events are retried.

@@ -495,6 +499,8 @@ handle_event(_, _, State, Data) -> callback mode is state_functions, the state must be of this type. + After a state change (NextState =/= State), + all postponed events are retried.

@@ -592,11 +598,11 @@ handle_event(_, _, State, Data) -> returns a list containing state_enter, the gen_statem engine will, at every state change, call the - state function + state callback with arguments (enter, OldState, Data). This may look like an event but is really a call - performed after the previous state function returned - and before any event is delivered to the new state function. + performed after the previous state callback returned + and before any event is delivered to the new state callback. See Module:StateName/3 and @@ -666,19 +672,19 @@ handle_event(_, _, State, Data) -> If the state changes or is the initial state, and state enter calls are used, the gen_statem calls - the new state function with arguments + the new state callback with arguments (enter, OldState, Data). Any actions returned from this call are handled as if they were appended to the actions - returned by the state function that changed states. + returned by the state callback that changed states.

If there are enqueued events the (possibly new) - state function + state callback is called with the oldest enqueued event, and we start again from the top of this list.

@@ -691,7 +697,7 @@ handle_event(_, _, State, Data) -> event_timeout() are handled. This may lead to a time-out zero event being generated to the - state function + state callback and we start again from the top of this list.

@@ -707,7 +713,7 @@ handle_event(_, _, State, Data) -> the next incoming message awakens the gen_statem, but if it is a system event it goes right back into hibernation. When a new message arrives the - state function + state callback is called with the corresponding event, and we start again from the top of this list.

@@ -806,7 +812,7 @@ handle_event(_, _, State, Data) ->

These state transition actions can be invoked by returning them from the - state function + state callback when it is called with an event, from @@ -870,7 +876,7 @@ handle_event(_, _, State, Data) ->

These state transition actions can be invoked by returning them from the - state function, from + state callback, from Module:init/1 or by giving them to enter_loop/5,6. @@ -903,7 +909,7 @@ handle_event(_, _, State, Data) -> Short for {timeout,Timeout,Timeout}, that is, the time-out message is the time-out time. This form exists to make the - state function + state callback return value {next_state,NextState,NewData,Timeout} allowed like for gen_fsm's Module:StateName/2. @@ -936,7 +942,7 @@ handle_event(_, _, State, Data) ->

This state transition action can be invoked by returning it from the - state function, from + state callback, from Module:init/1 or by giving it to enter_loop/5,6. @@ -947,7 +953,7 @@ handle_event(_, _, State, Data) -> From must be the term from argument {call,From} in a call to a - state function. + state callback.

Note that using this action from @@ -956,77 +962,48 @@ handle_event(_, _, State, Data) -> enter_loop/5,6 would be weird on the border of whichcraft since there has been no earlier call to a - state function + state callback in this server.

- + - - next_state - -

- The gen_statem does a state transition to - NextStateName - (which can be the same as the current state), - sets NewData, - and executes all Actions. -

-
-

- All these terms are tuples or atoms and this property - will hold in any future version of gen_statem. + State is the current state + and it can not be changed since the state callback + was called with a + state enter call.

-
-
- - - next_state

The gen_statem does a state transition to - NextStateName - (which can be the same as the current state), + State, which has to be + the current state, sets NewData, and executes all Actions.

-

- All these terms are tuples or atoms and this property - will hold in any future version of gen_statem. -

- + - - next_state - -

- The gen_statem does a state transition to - NextState - (which can be the same as the current state), - sets NewData, - and executes all Actions. -

-
-

- All these terms are tuples or atoms and this property - will hold in any future version of gen_statem. + StateType is + state_name() + if + callback mode + is state_functions, or + state() + if + callback mode + is handle_event_function.

-
-
- - - next_state @@ -1039,48 +1016,20 @@ handle_event(_, _, State, Data) ->

-

- All these terms are tuples or atoms and this property - will hold in any future version of gen_statem. -

- + - - keep_state - -

- The gen_statem keeps the current state, or - does a state transition to the current state if you like, - sets NewData, - and executes all Actions. - This is the same as - {next_state,CurrentState,NewData,Actions}. -

-
- keep_state_and_data - -

- The gen_statem keeps the current state or - does a state transition to the current state if you like, - keeps the current server data, - and executes all Actions. - This is the same as - {next_state,CurrentState,CurrentData,Actions}. -

-
-

- All these terms are tuples or atoms and this property - will hold in any future version of gen_statem. + ActionType is + enter_action() + if the state callback was called with a + state enter call + and + action() + if the state callback was called with an event.

-
-
- - - keep_state @@ -1104,17 +1053,6 @@ handle_event(_, _, State, Data) -> {next_state,CurrentState,CurrentData,Actions}.

-
-

- All these terms are tuples or atoms and this property - will hold in any future version of gen_statem. -

-
-
- - - - stop

@@ -1155,14 +1093,14 @@ handle_event(_, _, State, Data) -> by sending a request and waiting until its reply arrives. The gen_statem calls the - state function with + state callback with event_type() {call,From} and event content Request.

A Reply is generated when a - state function + state callback returns with {reply,From,Reply} as one action(), @@ -1227,7 +1165,7 @@ handle_event(_, _, State, Data) -> ignoring if the destination node or gen_statem does not exist. The gen_statem calls the - state function with + state callback with event_type() cast and event content Msg. @@ -1341,18 +1279,18 @@ handle_event(_, _, State, Data) -> call/2 when the reply cannot be defined in the return value of a - state function. + state callback.

From must be the term from argument {call,From} to the - state function. + state callback. A reply or multiple replies canalso be sent using one or several reply_action()s from a - state function. + state callback.

@@ -1562,7 +1500,7 @@ handle_event(_, _, State, Data) -> for efficiency reasons, so this function is only called once after server start and after code change, but before the first - state function + state callback in the current code version is called. More occasions may be added in future versions of gen_statem. @@ -1707,7 +1645,7 @@ handle_event(_, _, State, Data) -> The Actions are executed when entering the first state just as for a - state function. + state callback.

If the initialization fails, @@ -1829,13 +1767,13 @@ handle_event(_, _, State, Data) -> Module:StateName(enter, OldState, Data) -> - StateFunctionEnterResult + StateEnterResult(StateName) Module:StateName(EventType, EventContent, Data) -> StateFunctionResult Module:handle_event(enter, OldState, State, Data) -> - HandleEventResult + StateEnterResult Module:handle_event(EventType, EventContent, State, Data) -> HandleEventResult @@ -1856,20 +1794,20 @@ handle_event(_, _, State, Data) -> data() - StateFunctionResult = - state_function_result() + StateEnterResult(StateName) = + state_enter_result(StateName) - StateFunctionEnterResult = - state_function_enter_result() + StateFunctionResult = + event_handler_result(state_name()) - HandleEventResult = - handle_event_result() + StateEnterResult = + state_enter_result(state()) - HandleEventEnterResult = - handle_event_enter_result() + HandleEventResult = + event_handler_result(state()) @@ -1888,7 +1826,7 @@ handle_event(_, _, State, Data) -> {call,From}, the caller waits for a reply. The reply can be sent from this or from any other - state function + state callback by returning with {reply,From,Reply} in Actions, in Replies, -- cgit v1.2.3