Rahul,

Thanks for the response. I think I understand what you are saying but I
need to make sure if I got it so will paraphrase below (with some more
questions). Please let me know if this is correct.

> This (turning around and triggering an event on the state 
> machine) is a no-no based on the following:
> 
>  * Once a state machine receives external stimulus (as one or 
> more events), it must complete processing before it can reach 
> a stable state and begin to process others stimuli. As a 
> corollary, developer responsibility is in not interrupting a 
> state machine while it is processing external event(s).
>
>  * Commons SCXML uses JDK 1.4 and synchronized triggerEvent() 
> method(s). If the owning thread requests (such as in the 
> above example), Java will grant it the reentrant lock. Things 
> may seem fine here, but we've broken the first principle 
> (above bullet).

Ok, so let me see if I understand. You don't want to interrupt a state
machine while it is working, but you don't really know when the state
engine is working, which is why the concept of triggering events exists.
The events are processed by the engine when it has time to do so. Now,
the invoke, parentEvents, and cancel methods are all called by the state
engine (and hence the thread that is executing the engine) and the
engine blocks until these methods return. That means that when these
methods themselves trigger events the state engine must handle them
immediately  and would essentially give priority to those events and not
the events that the state engine has queued up. Not only that, but the
state engine will not register the ending of a state and the entrance of
another because it is handling the events in-line, which explains why I
saw so many parentEvents method calls.

That is why you want to be triggering events asynchronously, as
evidenced by the SimpleSCXMLInvoker class in the Commons SCXML project,
which triggers events in an asynchronous manner via the AsynchTrigger
class.

>  * <invoke> semantics work best when there is asynchronous 
> interaction. There shouldn't be any processing (of 
> significance) in any of the Invoker methods (invoke, 
> parentEvents, cancel), just the initiation of the processing 
> which will asynchronously continue to communicate with the 
> state machine as needed.

Normally I would think that you would want the state engine to stop
while the invoke process is running because that is what the state
engine should be doing at the time and the next state to visit will be
determined by the events triggered by the invoke. Any parallel states
would already be working in separate threads, so blocking in the invoke
should not cause parallel states to block. So the only reason I can see
for not wanting the invoke (and other methods) to take more than a
trivial amount of time is because the state engine could have events
waiting on it that would be prevented from being handled until the
invoke method returned. The only event I could think of that would be
triggered while the invoke method is being processed is the cancel
event, which you would want to actually stop the invoke process. Are
there any others?

I guess want to understand better what the consequences would be if I
did all my work in the invoke and parentEvents methods without spawning
threads except for actually triggering the events. I would prefer to
keep doing all my work in these methods and only spawn a thread for
triggering events. If I could limit the spawned threads to just
triggering events I could keep my design simple because the lifetime of
that thread would be very small. If I had to do a lot of processing in
those threads, then I would have to be more careful in the design to
avoid using too many threads at once (in other words thread pools) as my
system can involve hundreds if not thousands of simultaneous state
engine instances. 

> I suspect if you make the change above, these will generally 
> work as expected.

Yes, I saw that once I changed the code to trigger the events in
separate threads, the parentEvents method was triggered only for state
"step2" and not for the other state. However the process of triggering
an event while visiting the state "step2" still caused the cancel method
to be called.

> Could you please create an issue in JIRA [1] about the cancel 
> method in context of the invoke.done event? That'll ensure we 
> review it before the next release. Thanks.

Will do.

> Finally, as mentioned on the Commons SCXML home page, the 
> <invoke> bits are being worked out (in the W3C Working Group, 
> the draft lists a few things as TBD), so the implementation 
> also will need possible changes and/or improvements related 
> to the processing of <invoke> (both semantics and syntax, 
> such as event names) in future releases.

Ok, good to know. I'll stick with the invoke functionality because now
that I will use separate threads for triggering the events the only
issue I would need to work around is the cancel, which is not a big deal
for me.

A couple of final notes. Since I was seeing this issue because I was not
triggering events in separate threads, I would recommend that Commons
SCXML either improve how events are triggered or update the
documentation regarding invoke to point out that fact as it is not
readily apparent. It would be great if the Commons SCXML
SCXMLExecutor.triggerEvent and triggerEvents methods automatically
spawned threads to actually trigger the events so that users won't have
to worry about doing it themselves. To add flexibility, perhaps a
setting in the SCXMLExecutor class could be exposed so the user can turn
on or off whether events are triggered in separate threads.

I will look to see if Jira has an option for feature requests so I can
put that in.

Thanks again,

Elam Birnbaum

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to