[Ace-users] Integration of Event Handling for CORBA AMI and OpenDDS

M. Hayman hayman6 at comcast.net
Fri Sep 7 19:23:38 CDT 2007


Background: I've been doing a lot of research over the past few weeks
into the latest _performant_ middleware approaches to support a
variety of programs/projects where I work, ranging from HPC embedded
systems to LAN-based distributed computing systems (standard
requirements - multiple platforms/OS's, multiple languages, location
independence, etc.).  I'm not concerned with enterprise class problems
at this point, e.g. multi-site, WAN-based, Internet type applications
-- just those in the "single-site" domain for which underlying
broadcast & multicast transport protocols are an option.

I need to support building both services, per the SOA paradigm and the
tightly-coupled request/reply information exchange pattern, as well as
high performance (low latency, high throughput) streaming data/event
delivery capabilities utilizing the more loosely-coupled publish/
subscribe information exchange pattern -- inherent in EDA and DOA
architecture paradigms.  IMHO the combination of both information
patterns meets the full range of needs for the types of systems we
build.

Perhaps it's due to my background in building both real-time systems
and GUIs, but I have always preferred an event-driven application
component development model based upon registering event handlers/
callbacks with an event dispatcher/loop (e.g. like the ACE_Reactor
encapsulation of select() & Windows equivalent).  Junior software
developers sometimes take a while to get used to this asynchronous
programming approach, e.g. having to save state between events to
decide how to handle the next unexpected event, however I've found in
the long run that it produces to most performant and least complex/
buggy code -- often avoiding the need to escalate design complexity of
a particular component to support multi-threading and the inevitable
plethora of debug problems associated with lots of mutexes, shared
objects, concurrency issues, unintended tight-coupling/colocation
dependencies, etc. that come along with it, particularly for
inexperienced programmers.  In addition, I've come to detest long-
running event handlers and any system level call that has the
potential to block for long time periods (e.g. standard synchronous
CORBA), since this inevitably causes single-threaded applications to
"hang" and become unresponsive to other input events.  Same for using
semaphores for IPC - which I also hate.  Sure, you can spin off
potentially long-blocking synchronous calls into separate threads, but
for many relatively simple application components this is complication
I'd just as soon avoid (e.g. multithreaded apps) for the reasons I
just stated.

Having followed the DDS standard evolution over the past couple years,
it has led me to recently rediscovering the ACE/TAO stuff, in
conjunction with OpenDDS, after having dismissed it for a long time
(CORBA is "dead", right?) due to a forced foray into the wonderful
(non-performant) world of J2EE/.Net and web services.

----------------------

So, my current leaning based upon all of this and a lot more I won't
go into is toward utilization of the CORBA AMI ("new" since the last
time I looked at CORBA :) callback model for SOA/services/request-
reply, in combination with the DDS standard for DOA/EDA/publish-
subscribe.  Decoupling of the RPC reply event from a service request
invocation is desirable, as is the inherent event-driven nature of
DDS.  I like the fact that CORBA AMI allows you to avoid spinning off
a separate thread to handle a synchronous call so that your main
thread can remain event-responsive.  However, based upon my initial
cursory evaluation, it appears that the current OpenDDS implementation
for a subscriber _forces_ you into building a multi-threaded
application.  I'm off to look at RTI DDS and OpenSPLICE DDS as well,
but this is my current understanding for OpenDDS - which I'd prefer to
use for development/experimentation.

Every example of OpenDDS I have seen has a main() ending with a spin
loop containing a sleep() call.  I have always considered this "less
than optimal" design -- more like polling than event driven, usually
resulting in unnecessary context switches and built-in minimum event
response latency.  Is there no way to register the event associated
with a DDS data read with an ACE_Reactor-based (e.g. orb->run()) event
handler in a single thread?

If so (not at all obvious), an even more desirable capability would be
to allow OpenDDS subscriber/datareader event handlers (registered
callbacks) to be managed in a _single_ event loop that also handles
CORBA AMI events (e.g. orb->run() or a lower level ACE call)?.  Is
this possible?  The only way I can see doing this right now (without a
timer-based polling approach - yuk) is to have the separate OpenDDS
subscriber threads raise a signal or write to a pipe when a new data
sample arrives, and then register an event handler for the pipe FD
with the TAO event handler in the main thread.  But, this is starting
to get really ugly, since it's exactly the kind of stuff you want
framework/middleware code to handle for you.

What am I missing or not understanding?  I really expected that since
TAO and OpenDDS were put out by more-or-less the same group that it
would be easy to integrate them in the way I'm describing, e.g. a
single calling thread.  For many apps that we build, it would be very
nice for a [simple, single-threaded] client to be able to function
both as a CORBA AMI client as well as subscribe to a DDS topic or two
at the same time.



More information about the Ace-users mailing list