On 11-09-14 11:30, Johannes Wienke wrote:
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.

Yes, that might be possible to add.
But note that the current implementation isn't 'done' yet and several aspects of the current specification with regards to the event IO processor [1] aren't
completely implemented yet.
That functionally was initially on my plan for milestone 3 in the roadmap [2], but I already discovered I need some of this earlier on, and I've already started on some further internal refactoring and enhancements in this area.

But even when completed, such 'automatic' event coordination and execution still should remain an optional feature only to allow for other solutions where this coordination better be done within custom and domain specific client code.

My goal anyway is to first get the event IO processing in place as required by the specification.
But of course I'm also open for contributions and development support in 
general :)

[1] http://www.w3.org/TR/scxml/#eventioprocessors
[2] http://commons.apache.org/proper/commons-scxml/roadmap.html#Milestone_3:_External_communications_support


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.

Yes, in the current implementation you'll have to coordinate this yourself.
It should be trivial though to extend the SCXMLExecutor for your purpose to get 'notified' about such #addEvent invocations.


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.

Maybe you can try my suggestion above: extending SCXMLExecutor probably will allow for a trivial intermediate solution for this.


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

Done, thanks for pointing this out.


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.
Like I mentioned above, other use-cases might want/need to manage such event coordination themselves. So while it probably is feasible to add an optional and example wrapper solution handling this automatically on behalf of clients, it must leave room for other more domain specific solutions as well.



Cheers,
Johannes



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@commons.apache.org
For additional commands, e-mail: user-h...@commons.apache.org

Reply via email to