简体   繁体   中英

Why do gen_fsm state methods must return something?

I am currently reading LYAE and i am trying to understand why must gen_fsm state methods have to return anything at all according to the source

{reply, Reply, NextStateName, NewStateData}
{reply, Reply, NextStateName, NewStateData, Timeout}
{reply, Reply, NextStateName, NewStateData, hibernate}

{next_state, NextStateName, NewStateData}
{next_state, NextStateName, NewStateData, Timeout}
{next_state, NextStateName, NewStateData, hibernate}

{stop, Reason, Reply, NewStateData}
{stop, Reason, NewStateData}

Can someone explain to me if i have 3 state methods: a , b and c and the state machine would be defined as follows:

a()->
  receive
    something -> b();
    _ -> error(err)
  end.

b()->
  receive 
    somethingelse-> c();
    _ ->
  end.

Why would i ever need the return result of the next state method?

someMethod()->
   receive 
      _ -> 
           {next_state, NextStateName, NewStateData}=someNextMethod(),
          //why would i place code here? What could i possibly do with the above tuple ?
   end.

I do not understand why would i put code AFTER the call to the next state method? All calls are recursive so besides the initial state where i could actually do something after the fsm ended or threw, why would i put code in the other states?

You are correct, there is no need of return value, and you must have a recursive call to some function which will wait on a receive statement: it is necessary to make things evolve (because of immutability of variable) and to react to a new message.

The point is that your example is a one module state machine, while when you use a gen_fsm behavior, there are, at least 2 modules at play:

  • The implicit and generic gen_fsm behavior module itself
  • and the specific callback module you are writing.

Each module have very different roles.

  • The generic one is responsible to keep the state and receive the messages (it is why you must not take care of this in your code), it offers different kind of messages: synchronous or asynchronous, to one state or any state, via gen_fsm interface or "freely sent" messages... It manages also the operating modes: init, stop, code change... It manages also in background the interface with the OTP system. As it is a generic module, it cannot be aware of the states and transitions you want to define.
  • The callback module is called by gen_fsm (almost) each time it receives a message. The function called depends on the sate and the message. The callback module is responsible to define the states and transition you want for the state machine, it is done with the return value sent back to gen_fsm. The return value contains several fields, the next state is mandatory since the gen_fsm must know in which state to "go" - going in a state is an image, it is simply a state name stored in a variable and maintained by the main fsm loop - it can also maintain more information (generally also called state information which is confusing, for example for a door lock system the current secret code). The return value may also contain other things like the reply to the caller in case of synchronous message, a timeout before next incoming message, a request to stop the fsm...

In short, the gen_fsm is a simple recursive loop waiting for "event" messages which maintain, at least, the State_name variable. It uses helper functions stored in the callback module to describe its behavior. Not so far from what you say, but with the constraints brought by a generic module - and also the advantages of an integrated to OTP and well validated code.

   {next_state, NextStateName, NewStateData}=someNextMethod(),
   //why would i place code here? What could i possibly do with the above tuple ?

For instance:

  {next_state, NextStateName, NewStateData}=someNextMethod(),
  {next_state, NextStateName, NewStateData + 1}

Or:

  {next_state, NextStateName, NewStateData}=someNextMethod(),
  ModifiedStateData = do_calculation(NewStateData),
  {next_state, NextStateName, ModifiedStateData}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM