commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ate Douma <>
Subject Re: [SCXML] onentry executable content parallel to further transitions
Date Tue, 09 Sep 2014 14:28:21 GMT
On 08-09-14 18:59, Johannes Wienke wrote:
> Hi,
> thanks for the feedback work on this!
> On 09/07/2014 10:31 PM, Ate Douma wrote:
>> Actually, Commons SCXML already uses an event queue (one for internal
>> events and one for external events).
>> It is however the responsibility of separate client threads to only use
>> the executor #addEvent methods and only use a single client thread for
>> actual execution and event triggering on the state machine.
>> The bug you encountered was in the Commons SCXML *internal* delivery of
>> events which likewise (now) should use #addEvent but still used the
>> #triggerEvent method instead. This should now be fixed.
> Ok, assuming I am always using addEvents to fill the event queue, what
> is the correct pattern for a worker thread that then calls
> triggerEvents()? As far as I can tell from the implementation, this
> method returns immediately in case the queue is currently empty. Hence,
> implementing something like
> while (true) {
>      executor.triggerEvents();
> }
> should result in a loop wasting one CPU in case no external events need
> to be processed? This sounds wrong to me.

I think that is typically what you'll need to do, or else add some 'eventAdded' 
notification and coordination yourself (see below).

The initiating thread creating/owning the executor/engine instance likely also 
should be responsible for managing the statemachine execution: instantiating and 
then starting with go(), continuing with triggerEvents(), and if needed 
resetting through reset().

Other threads (as well as the 'owner' thread) can/should only add events to the 
queue through addEvent(Event), including threads dispatched from the engine itself.

Only a single owner thread should 'trigger' subsequent engine processing.
You can use executor.hasPendingEvents() to prevent the overhead of a trivial 
amount of CPU cycles, but executor.triggerEvents() with an empty queue will only 
impose a minimal overhead anyway.

Because only the 'owner' thread does (and may do) the actual execution of the 
engine, you're guaranteeing, and protecting (yourself!), no concurrent 
statemachine processing will happen. The (current) executor intendedly does NOT 
enforce this (as you noticed) with synchronization blocks or otherwise.

It remains that your owner thread will have to use some timer based triggering 
of the executor, but that is typical when dealing with multiple thread 
coordination/synchronization. Or else you could consider extending/intercepting 
the executor to 'notify' your owner thread when new events are added to the 
external queue.
But with that you'll enter a domain specific implementation, not easily 
generalizable in Commons SCXML (although I'm happy to review patches ;) ).

Regards, Ate

> Cheers,
> Johannes

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message