avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Berin Loritsch <blorit...@apache.org>
Subject Multithreaded Message from the Devil ;P
Date Thu, 09 Oct 2003 15:08:51 GMT
Playing Devil's advocate here, so the opinions and views expressed in this
message are not necessarily my own, and may in fact be totally made up.

I may or may not make sense here.  I suffered some back injuries in a minor
automobile accident on Monday morning, and my concentration has been lacking
due to pain.  Hopefully this is one of my lucid moments... ;P

The talks of what a container is supposed to do and the component is supposed
to do got me thinking a bit.  (could be good or bad).  So before we make the
component model different, or impose more requirements on the container, let's
do the big picture thing.  Why do we use components?  Because they make it
easier to manage change in an application (among other reasons).  Why do we
have containers?  Because they make it easier to manage components and apply
cross-cutting concerns consistently to all the components.  A large repository
of reusable components is a pipe dream.  There will be some that can be
reused to be sure, but not the cornicopia early adopters of COP wanted us to

So what types of problems are we solving with CBD?  Each problem domain has its
own set of challenges.  The question is how formal do we want our components
to be?  If we make everything completely hard, then new features such as thread
monitoring and such would be difficult to mix in to a containment architecture.
If we make everything completely soft (like JavaBeans), then we can run into
stability and security issues rather quickly.  So we need a balance.

It was mentioned in the "Monitored Components" thread that multi-threading is
really the option of the handler.  That *can* be the case, but is not
necessarily the case.  With the arrival of event based architectures like SEDA
and NIO/NBIO, multithreading can be completely orthagonal to the whole handler/
monitor picture.

The traditional view of a connection listening system consumed one thread to
monitor the incoming socket, and then kick off events to a handler using a
thread pool, or just a new thread per request.  This is an N+1 resource
consumption, and usually the thread pool has to become unnecessarily large
to handle the load.  Threads are precious resources, so the solution can only
scale so far.

In a more modern view, what happens is that we have one or more threads
monitoring the *same* socket, and call the handler code in-line.  I.e. no
additional threads are called.  This is an N resource consumption for threads,
but it also has the advantage of being able to use the monitoring thread to
run the handling code.  In theory, this scales up very well, even to the point
of handling 10,000+ users simultaneously in one JVM!

There are some caveats though.  The read messages will come in piece-meal, so
the information has to be cached in some sort of message context until the whole
is received.  The response can be sent as soon as the processing is complete for
the read cycle, but it can't be committed until the socket is ready to accept
a "write".

It can be worked around if all the components in the processing chain can handle
events, and process things a little at a time.  However, most people are used
to handling things traditionally, or all at once.  It's a high impedence to
learn enough to experiment.

The thing is you will never be able to have a one size fits all solution.  Ever.
It can be a holy grail, and an inspiration to help us take great strides toward
that goal, but each problem domain has its challenges and not all of them will
translate to new problem domains.

The best thing we can do is to make simple things really easy, and hard things
possible.  It would be incredible to open up the world to new inventive ideas
that would change the way they think about the development world.  But that is
not our job.  I think the reason we are all here together is because we have in
common that Avalon components work for our kinds of problems.  We are all
working to make them easier to use and open to all developers, but some folks
are resistant to change for the sake of being resistant to change.  Don't worry
about them.

As far as component health monitoring, exactly what would we monitor?
Additionally, what would we do with the information once we have it?  Lastly,
how much of an inconvenience would it be for the component writer to use the

There are ideas that maybe possibly, we would want to monitor threads created
by the component.  What if the container made it a security policy that your
sandboxed Startable component was not able to create threads?  Does that mean
that there is no way for the component to *use* them?  There are ways, such
as using the CommandQueue from the Event package.  Another component is
responsible for running the asynchronous code, not the sandboxed one.  That
works in many situations.  However, most of the components I write are passive
in nature.  There is no reason to actively monitor it, or to burn up precious
threads to monitor them.

The question is where is the balance?  Where should the container leave off
and the component start?

There are many different views on this.  For instance, many people still hold
to the monolithic approach, and want to combine all management and application
logic into one large executable.  Then, there is where Fortress and to some
extent Merlin is, which we have a complex kernel that runs all the aspects for
the application components.  Lastly, we have the nano-kernel type approach that
I have bantered about in the past, which looks like what Leo is inferring.  That
approach means that we have some components which act to help the container do
its job.  In a sense, they are privileged/container components.  In another
sense, they can probably also be used in application logic.  So should we make
a distinction?  Maybe not.  But then again, we also need a way to implement
sandboxes in the future.  That way we would need to allow certain privileges
to some components, and deny them to others.  Perhaps we might even need a
way to identify security constraints at the service level.  For instance, the
socket handling code referred to above would need to be able to listen to and
manage sockets--all implementations.

Anyhoo, I am probably rambling by now, so I will allow for comments.


"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin

To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org

View raw message