qmuntal / stateless

Go library for creating finite state machines

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Model vs Machine

jwenz723 opened this issue · comments

This is a question, not an issue. I am trying to gather the intended method of usage for this package.

I am wondering if there is a way with this package to define the valid triggers/states one time (maybe in func main(). Then afterwards, create a single StateMachine instance per incoming HTTP request using the previously created configuration (triggers/states)?

I am hoping to use this package in a way where I would define the triggers/states on application start up then I would use a new StateMachine instance for each new incoming HTTP request because my app is stateless. So for each incoming request I would do the following:

  1. retrieve current state from an external durable storage
  2. create a new StateMachine with the current state and the pre-defined valid triggers/states
  3. fire triggers according to the particular HTTP endpoint
  4. store end state into external durable storage and return data to HTTP endpoint caller

Hi @jwenz723, there is no need to instantiate a new StateMachine on every HTTP query, just reusing the one you created in your func main() should cover your use case.
Take into account that calls to the state storage are already thread-safe and that the FiringQueued mode enqueue trigger fires so only one trigger is executed concurrently.

I understand that the state transition triggers can execute in a thread-safe way, so you would only need 1 StateMachine instance per unique entity. However, my my scenario there are multiple entities which each have their own state. For example....

In the README you create a single StateMachine instance like this:

phoneCall := stateless.NewStateMachine(stateOffHook)

From my understanding this StateMachine represents a single phone call. In my scenario, I would like to have many phone calls exist at the same time, and therefore, each one of these phone calls should have their own StateMachine instance (I assume), because each phone call should be able to transition between states independent of the state of other phone calls.

Hopefully this makes sense. Please let me know if there is a better way to achieve state management of multiple entities.

Oh, i get it now. What I would do is create a function that returns a configured state machine on its initial state, something similar to:

func NewPhoneCall() *StateMachine {
  phoneCall := stateless.NewStateMachine(stateOffHook)
  phoneCall.Configure(stateOffHook).Permit(triggerCallDialed, stateRinging)
  return phoneCall
}

This way you centralize the state machine configuration and you just call it whenever a new one is needed.

Does it work for you?

That makes sense. Thank you.