Scheduling internal transitions within callbacks
Hi, I have a particular need and want to get your views and the best way to deal with this. Here are my transitions -
[1]initial=disconnected [2]disconnected: on "connect"->connected [3]connected: on "disconnect"->disconnected [4]connected: on "echo" -> "connected" [5]connected: on "echolimit_met"->"up"
Please note that on line [4], the transition is from connected->connected which results in NoTransitionError and that is ok.
Now, any number of echo events might happen in connected state. But, after 3rd echo I need a transition to "up"
I intend to do this transition (using a echolimit_met event) after the current event has been processed. There is currently no way to do this within the callbacks and I'm doing this right now by starting a new goroutine within the callback
go func() {
fsm.Event(e)
}()
```
Do this approach seem right to you?
Perhaps we could have a fsm.ScheduleLater(e) which the fsm executes towards the end of current event processing.
Interesting case.
I don't have any feedback right now, anyone else here who might want to chime in?
I have a similar need. I need a transition to conditionally trigger another transition, as do #36 and #38. Doing this in a goroutine is a hack, but (I believe) the only other way to do this without deadlock is like so
fsm.Event(event)
if fsm.Current() == "connected" && echos > 2 {
fsm.Event("echolimit_met")
}
You thus lose a bit of the power of abstracting the problem in a fsm. If you have enough of these cascading transitions (like I do), it's probably worth it to wrap fsm in an abstraction that encapsulates these cascades. Although it'd be nice if the package could do this natively.
That is what I did eventually. I created a abstraction on top of the FSM and rather than executing the next event in a goroutine, I queued it up and executed it at the end of the current transition.
So, w.r.t this example - When in connected state, while echo<3, cancel event else queue up "echolimit_met" event
Perhaps, it would be good to have the ability to define the fsm like this -
{"connected","echo",func(e *fsm.Event) (string,err){ ... },{"no_change": "connected","move_to_up":"up"}}
Where the callback is executed and the target state is determined by a label returned from the callback (or could simply return the target state rather than a label).
Any update on this?
Any update on this?
You can give the version in our fork over in https://github.com/alfaview/fsm/pull/1 a try. :)