commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Johannes Wienke <jwie...@techfak.uni-bielefeld.de>
Subject Re: [SCXML] onentry executable content parallel to further transitions
Date Thu, 11 Sep 2014 09:30:03 GMT
Hi,

On 09/09/2014 04:28 PM, Ate Douma wrote:
> On 08-09-14 18:59, Johannes Wienke wrote:
>> 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).

Wouldn't it be much nicer from a user perspective if the executor could
offer something like waitForNextEvents() or
waitUntilEventsInExternalQueue()? Depending on the use case, this is
much easier to implement internally than externally.

Moreover, since SimpleScheduler now uses addEvent, too, I cannot even
know all events that enter the state machine, or am I wrong? So I am
doomed to implement a busy waiting loop.

> 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.

But if I know that there are currently no pending events, then I can't
do anything else then polling in a busy loop. Either I have to do this
quite often and just increase CPU load or with a larger sleep statement
I will add an unwanted delay in processing.

> 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.

Ok, got it. Could you please fix up the respective FAQ entry that is at
least confusing in that respect:
https://commons.apache.org/proper/commons-scxml/faq.html#many-threads

> 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 ;) ).

Is this really domain specific? Something simple as using notify on an
object available to clients whenever new events enter the external queue
would already be sufficient to implement a proper synchronization system
without busy waiting. And this would be a huge improvement several use
cases that I can imagine.

Cheers,
Johannes

-- 
Johannes Wienke, Researcher at CoR-Lab / CITEC, Bielefeld University
Address: Inspiration 1, D-33619 Bielefeld, Germany (Room 1.307)
Phone: +49 521 106-67277


Mime
View raw message