gen_statem provides a generic state machine behaviour
      that for new code replaces its predecessor
      gen_fsm
      since Erlang/OTP 20.0. The gen_fsm behaviour remains
      in OTP "as is".
    
    
Note
      
	If you are new to gen_statem and want an overview
	of concepts and operation the section
	
	  gen_statem Behaviour
	
	located in the User's Guide
	
	  OTP Design Principles
	
	is recommended to read before this reference manual,
	possibly after the Description section you are reading here.
      
     
    
      This reference manual contains type descriptions generated from
      types in the gen_statem source code, so they are correct.
      However, the generated descriptions also reflect the type hierarchy,
      which sometimes makes it hard to get a good overview.
      If so, see the section
      
	gen_statem Behaviour
      
      in the
      
	OTP Design Principles
      
      User's Guide.
    
    
    
      gen_statem has got the same features that
      gen_fsm
      had and adds some really useful:
    
    
      - Co-located state code
- Arbitrary term state
- Event postponing
- Self-generated events
- State time-out
- Multiple generic named time-outs
- Absolute time-out time
- Automatic state enter calls
- 
	Reply from other state than the request, sys traceable
      
- Multiple sys traceable replies
- Changing the callback module
      Two
      callback modes
      are supported:
    
    
      - 
        
	  One for finite-state machines
          (gen_fsm like),
          which requires the state to be an atom and uses that state as
          the name of the current callback function.
         
- 
        
	  One that allows the state to be any term and
          that uses one callback function for all states.
         
      The callback model(s) for gen_statem differs from
      the one for gen_fsm,
      but it is still fairly easy to
      
	rewrite from
       gen_fsm to gen_statem.
    
    
      A generic state machine server process (gen_statem) implemented
      using this module has a standard set of interface functions
      and includes functionality for tracing and error reporting.
      It also fits into an OTP supervision tree. For more information, see
      OTP Design Principles.
    
    
      A gen_statem assumes all specific parts to be located in a
      callback module exporting a predefined set of functions.
      The relationship between the behavior functions and the callback
      functions is as follows:
    
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
      types,
      so the callback functions can know the origin of an event
      and how to respond.
    
    
      If a callback function fails or returns a bad value,
      the gen_statem terminates, unless otherwise stated.
      However, an exception of class
      throw
      is not regarded as an error but as a valid return
      from all callback functions.
    
    
    
      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
      callback mode
      that the callback module defines with the callback function
      Module:callback_mode/0.
    
    
      When the
      callback mode
      is state_functions, the state must be an atom and
      is used as the state callback name; see
      Module:StateName/3.
      This co-locates all code for a specific state
      in one function as the gen_statem engine
      branches depending on state name.
      Note the fact that the callback function
      Module:terminate/3
      makes the state name terminate unusable in this mode.
    
    
      When the
      callback mode
      is handle_event_function, the state can be any term
      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
      states so that you do not accidentally postpone an event
      forever creating an infinite busy loop.
    
    
      When gen_statem receives a process message it is
      converted into an event and the
      state callback
      is called with the event as two arguments: type and content.
      When the
      state callback
      has processed the event it returns to gen_statem
      which does a state transition.
      If this state transition is to a different state,
      that is: NextState =/= State, it is a state change.
    
    
      The
      state callback
      may return
      transition actions
      for gen_statem
      to execute during the state transition,
      for example to reply to a
      gen_statem:call/2,3.
    
    
      One of the possible transition actions
      is to postpone the current event.
      Then it is not retried in the current state.
      The gen_statem engine keeps a queue of events
      divided into the postponed events
      and the events still to process.
      After a state change the queue restarts
      with the postponed events.
    
    
      The gen_statem 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.
    
    
      The
      state callback
      can insert events using the
      transition actions
      next_event
      and such an event is inserted in the event queue
      as the next to call the
      state callback
      with.
      That is, as if it is the oldest incoming event.
      A dedicated
      event_type()
      internal can be used for such events making them impossible
      to mistake for external events.
    
    
      Inserting an event replaces the trick of calling your own
      state handling functions that you often would have to
      resort to in, for example,
      gen_fsm
      to force processing an inserted event before others.
    
    
      The gen_statem engine can automatically
      make a specialized call to the
      state callback
      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 explicitly insert an event
      at the state transition,
      and/or to use a dedicated state transition function,
      but that is something you will have to remember
      at every state transition to the state(s) that need it.
    
    
Note
      
If you in gen_statem, for example, postpone
        an event in one state and then call another state callback
        of yours, you have not done a state change
	and hence the postponed event is not retried,
	which is logical but can be confusing.
      
     
    
      For the details of a state transition, see type
      transition_option().
    
    
      A gen_statem handles system messages as described in
      sys.
      The sys module can be used for debugging a gen_statem.
    
    
      Notice that a gen_statem does not trap exit signals
      automatically, this must be explicitly initiated in
      the callback module (by calling
      process_flag(trap_exit, true).
    
    
      Unless otherwise stated, all functions in this module fail if
      the specified gen_statem does not exist or
      if bad arguments are specified.
    
    
      The gen_statem process can go into hibernation; see
      proc_lib:hibernate/3.
      It is done when a
      state callback
      or
      Module:init/1
      specifies hibernate in the returned
      Actions
      list. This feature can 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,
      as hibernation can be too costly
      to use after every event; see
      erlang:hibernate/3.
    
    
      There is also a server start option
      
	{hibernate_after, Timeout}
      
      for
      start/3,4,
      start_monitor/3,4,
      start_link/3,4 or
      enter_loop/4,5,6,
      that may be used to automatically hibernate the server.
    
    
      If the gen_statem process terminates, e.g. as a result of a
      function in the callback module returning {stop,Reason}, an exit
      signal with this Reason is sent to linked processes and ports. See
      
      Processes in the Reference Manual for details regarding error
      handling using exit signals.