Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to queue/auto-transition after entering state #139

Closed
angularsen opened this issue Nov 2, 2017 · 6 comments
Closed

How to queue/auto-transition after entering state #139

angularsen opened this issue Nov 2, 2017 · 6 comments

Comments

@angularsen
Copy link

Hi, one issue I keep bumping into is - how do I queue or auto-transition to a state, from within transition event callback?

There are two related usecases for this:

  1. State machine should transition to the next state in a sequence of states, based on some condition
  2. Writing a unit tests for a state machine that may auto-transition to states, using onTransition callback to trigger transitions before the next queued transition takes effect

My simplified state flow is something like this:

IDLE--start()-->DETECT_FACES--detected(faces)-->IDENTIFY_FACES-->identified(persons)-->DETECT_FACES-->detectedInTheMeantime(faces)-->IDENTIFY_FACES...

DETECT_FACES kicks of a face detector worker that runs asynchronously and triggers face-detected events.
IDENTIFY_FACES starts an asynchronous process to identify faces that can take several seconds.

So far I've accomplished this by storing a buffer of facesDetectedInTheMeantime outside the state machine and using setTimeout() to invoke the transition upon entering DETECT_FACES, but this seems very hackish to me and probably not very deterministic. Ideally, there was a way to queue transitions or a lifecycle event that is invoked after the transition has fully completed so you can enter new states from it, but maybe that would need to use a mechanism similar to setTimeout and not really gain anything.

Am I way off on the way I am thinking here?

@rickbsgu
Copy link

rickbsgu commented Nov 9, 2017

Does an asynchronous transition (return a promise) address the issue?

@angularsen
Copy link
Author

No I don't think so, my understanding is that the statemachine will be "in-transition" for as long as it takes the promise to complete. In that timeframe, no other transitions are allowed. If I got that right, I think it's better to have immediate transitions and instead kick off background work that at some point later trigger a new transition - or fail if the state changed in the meantime and that transition is no longer valid.

@rickbsgu
Copy link

rickbsgu commented Nov 9, 2017

No I don't think so, my understanding is that the statemachine will be "in-transition" for as long as it takes the promise to complete.

Right.

I think your analysis is correct - triggering (one or more) background process shouldn't hang a transition. The following state might be something as simple as 'waiting for face identification' to whatever the next operative state is in the app, regardless of whether the the face identification completed.

Then, you can define transitions from multiple possible states at that point to a 'face identification complete' state when the background process completes, and then handle any cleanup from there.

I don't know if it's analogous, but I had a somewhat similar situation with an 'inactivity timeout' trigger (that could interrupt the flow at any point.) That was the way I handled it.

@angularsen
Copy link
Author

Right, so currently the only way to have the state machine auto-transition when there is no async operation is to use setTimeout() with 0ms delay in order to trigger a transition without getting a "pending transition" error. I could use "goto", but that does not trigger the lifecycle events.

@rickbsgu
Copy link

rickbsgu commented Nov 9, 2017

Yes -- see my comment in #143. So, what will likely get you is that the process will complete while you're in another transition. So, you'll likely have to put a 'process-completed' transition call in a timeout so it allows any current transitions to complete.

(A useful facility in the fsm might be the ability to abort any active transitions, although that might leave things in an unstable state.)

(All this if I'm reading your issue correctly...)

@angularsen
Copy link
Author

Yup, makes sense. I guess I don't see any better way to achieve this than my current approach then, so I'll close this. Thanks for the responses!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants