appccelerate / statemachine

A .net library that lets you build state machines (hierarchical, async with fluent definition syntax and reporting capabilities).
Apache License 2.0
488 stars 128 forks source link

Event catching weird behaviour #71

Closed dilandau2001 closed 3 years ago

dilandau2001 commented 3 years ago

Hello. I have being using the library for quite long, and I am just noticing an issue I did not encounter before as far as I remember.

I have tried with both AsyncPassiveStateMachine and with AsyncActive and have same result.

this state machine has states similar to this: NotConnected, Connected, Disconnected, Connecting. and event triggers like: ConnectionDetected, DisconnectionDetected, ElapsedTime, CheckStatusFailed

the elapsed time event is being fired by a system.Timers.Timer when elapsed time is fired a call is done to a service. When this call is done and it fails it both fires DisconnectionDetected and CheckStatusFailed (I have tried also with only one of them but still happens)

When DisconnectionDetected is fired, I can see that the code

await _machine.Fire(EventTrigger.DisconnectionDetected) is called.

The code continues, it does not hang in previous line. Previous line is executed fast. DeclinedEvent is not fired, Exception not fired either.

The state machine just continues working as if no event was ever triggered.

Finally, after several minutes, 2-3 minutes, it eventually executes the fired trigger. In the meantime, multiple calls to the service and multiple DisconnectionDetected triggers.

I have tried all I can think of and I am not sure what is wrong, or why the trigger is left waiting somewhere.

thanks in advance, any help would be really appretiated.

ursenzler commented 3 years ago

Hi!

Multi-threading stuff is always hard to debug. I don't understand from your message what's going on, but I can explain some general things:

It's probably not this, but make sure that the ThreadPool is not thread-starved (there are no threads available to run any code).

Let me know if that helps, and what you find while debugging with the extension. Then we can look further.

dilandau2001 commented 3 years ago

thanks. It was helpful. I found the problem thanks to it. When the timer elapses it adds the "ElapsedTime" to the queued events. When this first event is firing, it calls a very long time task, because the service in this case is not reachable and then network time outs. In the meantime, the timer keeps adding ElapsedTime to the events queue every time it elapses. when first event does return, it adds disconnectionDetected to the queue of events. Behind, 30 elapsedTime which will also execute the long running task. By now I will disable timer while the check is being done.

Is there any recommendation to execute periodic checks in a specific state?

I was using In(state) On(ElapsedTime).Execute(Check)

Being ElapsedTime fired by the timer.