Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: StateMachine Action Notification Chains Problem  (Read 12357 times)
orensol
Newbie
*
Posts: 6


View Profile Email
« on: February 02, 2010, 03:29:07 »

Hi all,

I am using the StateMachine, and have the following setup:

:
<fsm initial="INITING">
   <state name="INITING"}>
   <transition action="INIT_DONE" target="MODULE_INITING"/>
   </state>
   <state name="MODULE_INITING" changed="CHANGED_MODULE_INITING">
   <transition action="MODULE_INIT_DONE" target="MODULE_PLAYING"/>
   </state>
   <state name="MODULE_PLAYING" changed="CHANGED_MODULE_PLAYING">
   </state>
</fsm>

Now, I have a mediator that is interested in both CHANGED_MODULE_INITING and CHANGED_MODULE_PLAYING. The problem is that my ChangedModuleInitingCommand initiates the transition to MODULE_PLAYING by sending a notification of CHANGE and type MODULE_INIT_DONE, but then the mediator gets the CHANGED notifications in LIFO order, so it is actually in INITING state while it should be in PLAYING state.

I assume the problem is the timing of the call to action MODULE_INIT_DONE, but as I have read in the release notes, the specific-state change is where you should initiate calls to other actions.

So any idea what I am doing wrong and how to solve this?

Thanks,
Oren
Logged
mariusht
Full Member
***
Posts: 26


View Profile Email
« Reply #1 on: February 02, 2010, 07:49:32 »

:
The problem is that my ChangedModuleInitingCommand initiates the transition to MODULE_PLAYING by sending a notification of CHANGE and type MODULE_INIT_DONE
Your ChangedModuleInitingCommand should
sendNotification(StateMachine.ACTION, null, ShellFacade.MODULE_INIT_DONE);


Mariush T.
http://mariusht.com/blog/
Logged
orensol
Newbie
*
Posts: 6


View Profile Email
« Reply #2 on: February 02, 2010, 08:21:23 »

Yes, that's exactly what it does (I mistyped CHANGE for ACTION when posting).

And still the mediator gets the change events in LIFO order.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: February 02, 2010, 01:59:45 »

What this issue points out is the implied 'asynchronicity' of States in the StateMachine. Th

Each State must be isolated from the next by a break in the thread of program execution. There are three ways this can happen in Flash:

 * A server interaction
 * A timer
 * A user interaction

The reason your Mediator is getting the calls in LIFO order is because there was no break in the thread of execution between state changes.

... a mediator that is interested in both CHANGED_MODULE_INITING and CHANGED_MODULE_PLAYING. The problem is that my ChangedModuleInitingCommand initiates the transition to MODULE_PLAYING by sending a notification type MODULE_INIT_DONE, but then the mediator gets the CHANGED notifications in LIFO order, so it is actually in INITING state while it should be in PLAYING state.

There are (at least) two observers for the CHANGED_MODULE_INITING announcement: ChangedModuleInitingCommand (which is the first one on the notification list, registered prior to the mediator) and the mediator that's interested in both the CHANGED_MODULE_INITING and CHANGED_MODULE_PLAYING.

So when CHANGED_MODULE_INITING goes out, the Command is notified first, and you have it immediately sending out MODULE_INIT_DONE which leads to the StateMachine sending out CHANGED_MODULE_PLAYING.

Remember that Flash is single threaded. So we haven't finished notifying all the interested parties for the first notification before the second one is sent out. The View begins the notification loop for the second note and the mediator recieves CHANGED_MODULE_PLAYING. Eventually the thread of execution stops here, and so Flash returns to its call stack and sees that the last thing it was doing was notifiying observers about CHANGED_MODULE_INITING and it picks up where it left off, and the mediator then recieves the first note AFTER the second one.

-=Cliff>
Logged
orensol
Newbie
*
Posts: 6


View Profile Email
« Reply #4 on: February 03, 2010, 12:36:15 »

Hi Cliff,

So if I need the next state to fire from within the command, and I have no server or user interaction, I must use a timer?

Also, maybe that implies that the two states should be combined into one?

Oren
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #5 on: February 03, 2010, 08:20:02 »

maybe that implies that the two states should be combined into one?
You got it. If you've just got a block of synchronous code to run, then what is the value of having a State bounding it? Its just added complexity.

-=Cliff>
Logged
fmjrey
Newbie
*
Posts: 7


View Profile Email
« Reply #6 on: April 25, 2010, 09:06:48 »

So in the case of the SeaOfArrows web site, which code is available at http://seaofarrows.com/srcview/ and which is described in the puremvc.tv, the shell states STARTING and PLUMBING and CONFIGURING should be merged into one state.

I say this because STARTED is just the initial state with no associated commands. The action STARTED is sent by the initial command after the FSM is injected, thus jumping to PLUMBING. And the last thing the shell PlumbCommand does is trigering the transition to the CONFIGURING state with:
sendNotification( StateMachine.ACTION, null, ShellFacade.PLUMBED );

So the call stack will look like this:
sendNotification( StateMachine.ACTION, null, ShellFacade.STARTED );
  PlumbCommand.execute()
    sendNotification( StateMachine.ACTION, null, ShellFacade.PLUMBED );
      ConfigureCommand.execute()
        async loading of xml
    sendNotification( CHANGED, currentState, ShellFacade.CONFIGURING );
  sendNotification( CHANGED, currentState, ShellFacade.PLUMBING );


As you say earlier it does make things a lot more complicated. So I'd be curious to know about:
1. What are the benefits in the case of SOA/MediaTurbine?
2. Any advice with this practice of chaining states without async break?
3. Any constraints in the use of this practice besides avoiding the use of the CHANGED notifications (these are sent in LIFO order)?
« Last Edit: April 25, 2010, 09:11:14 by fmjrey » Logged
fmjrey
Newbie
*
Posts: 7


View Profile Email
« Reply #7 on: April 25, 2010, 10:28:16 »

I'll just give my own hint with question #2:
A case where this chaining is necessary is when the next state in the chain can also be triggered by some other event, most notably an async event such as user interaction, thereby requiring its encapsulation and reuse. So in the case of SOA if some user interaction were to require a new xml config, the CONFIGURING state will need to stand on its own while STARTING and PLUMBING could be merged.
Logged
fmjrey
Newbie
*
Posts: 7


View Profile Email
« Reply #8 on: April 28, 2010, 01:06:11 »

For question #3:
Avoid such chaining if the transition occurs many times without an asynchronous break.
This is to avoid an ever growing call stack, which piles up every transition made until the next asynchronous request. I'm assuming here that the calling stack must terminate before the flash engine can fire the listener of an asynchronous call. Is this right?
In any case such situation would certainly mean a misuse of a state for something too transient.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #9 on: April 28, 2010, 08:52:16 »

1. What are the benefits in the case of SOA/MediaTurbine?
This app was intended to demonstrate the use of the StateMachine and MultiCore, primarily to give talking points for a presentation. In its case the main benefit is an instructional one on how to conceptualize your application around a state machine. I must admit that I could've probably come up with something better, but I was working evenings from a hotel room for 3 months, which I find negatively affects the ability to output meaningful spare time work, but that's another story... :)

2. Any advice with this practice of chaining states without async break?
Well, from experience on a moderately complicated state machine in my most recent application (Zarqon), I have reaped a lot of benefit from breaking everything into states. Most of them are async, but several of them are not. I've had to rearrange the order of some of the states and insert new states along the way, and I found that it facilitated this sort of thing with ease. There are definitely places where it could conceptually be broken into more states, but it would add more complexity than is really necessary. So, at some point it becomes something of an aesthetic decision in the architecture.

3. Any constraints in the use of this practice besides avoiding the use of the CHANGED notifications (these are sent in LIFO order)?
Not really. Just understanding the order of notifications coming out of and going into the state machine at any given point is the key. Don't let it be magic; read the source code, and use the debugger. It's pretty simple, but as @orensol found, it can surprise you if you don't adequately predict its behavior.

-=Cliff>
Logged
Pages: [1]
Print