avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Berin Loritsch" <blorit...@apache.org>
Subject RE: ContainerManager and Sub-containers
Date Wed, 05 Jun 2002 13:17:16 GMT
> From: Leo Simons [mailto:leosimons@apache.org] 
> String operations can usually be cached. I know zip about 
> cocoon, basically, but why is it not possible to have
> static String Generator.FOO_ROLE = Generator.ROLE + "/fooo"!;

However, for most people it is just quicker to do this:

manager.lookup (Generator.ROLE + "/fooo");

which is more error prone, slower, and has all the other issues
associated with dynamic strings.  It does not address the underlying
problem at a level where all developers will take advantage.

> > The fact that they overlap would mean that really there 
> shouldn't be 
> > implementations bound to separate locations.  There should be one 
> > location. They aren't distinct enough.  It would be like 
> blocking IO 
> > vs. non-blocking
> > IO.  One scales better than the other, but they essentially 
> do the same
> > thing.
> Still don't see the relevance. This is an analysis problem, not?

Yes and no.  The FileGenerator came first, and the StreamGenerator
was never cacheable.

The relavance in the scope of this conversation is to show that
there are still limitations to the Generator.ROLE + "/stream"
approach when you have two implementations that are effectively
the same.

The purpose of the Generator.ROLE + "/foo" is not to arbitrarily
select between several implementations of a Generator, but to
further define the _ROLE_.

It is like the difference between a persistent store and a temporary
store.  Using this example, we could have implementations and roles
that are bound to:

Store.ROLE                 - Default Store--user doesn't care
Store.ROLE + "/volatile"   - Temporary store--entries not guaranteed to
Store.ROLE + "/persistant" - Persistant store--entries are persistant

> > Here is something that I have been thinking about lately.
> > How can we have our cake and eat it too?  How can we have a fast 
> > performing component hash without the limitations of the String.
> 1 - don't use String (use int, long, char[])
> 2 - cache Strings (define Strings as early as possible, 
> minimise operations on String, cache operations on String)
> the advantage of 1 is a cleaner (smaller) implementation. The 
> advantage of 2 is a more intuitive API. 

And my proposal merged the two advantages!  We use a long to determine
the actual entry for the component, but we have the CM resolve the
string operations to the long.  That means that the CM is in charge of
long to component mapping, and that runtime calls on the CM are much
more efficient.

> > In high transaction environments, this is critical.  My previous 
> > attempts at coming up with something that would work for 
> everyone have 
> > not been up to par.  I am still stuck on trying to come up with 
> > something.  I think
> > a query object is better than Strings.
> For high performance, yes. For general use, an unneccessary 
> level of indirection or an extra method call as you use 
> strings anyway.

Not necessarily.  This approach forces the user to take advantage of
string caching, and the key (like the event PreparedQueue) is guaranteed
to exist.  You know prior to request if the component you want exists
or not.  You also don't have to worry about messy exception handling.
Trading one line for several is in my opinion a worthy cause.

Comparison (the component may not exist):

TestComponent myComp = null;

    myComp = (TestComponent) manager.lookup( TestComponent.ROLE );

catch (ComponentException ce)
    getLogger().error("Missing component", ce);
    if (null != myComp) manager.release( myComp );

Request req = manager.createRequest( TestComponent.ROLE );

if (null == req)
    getLogger().error("Missing component");
    TestComponent myComp = manager.lookup( req ); // guaranteed to be

We saved three lines of code, and increased readability and
of the code at the same time!  By three lines of code, I am counting
line that has text (excluding comments and blank lines).  As for
complexity analysis you add one for every block of code (i.e. every time
have a new bracket).  We even saved here.

> How often do you need to server millions of requests a day 
> where the bottleneck is not somewhere else?

9 times out of 10, the problem is in synchronization between many
threads.  The ECM is one major source of thread contention issues.
is proof that by removing as many chances for thread contention as
dramatically increases the speed in which you can resolve requests.

Using the Request based component resolution, we gain further benefits
the ability to arange the components in any fashion we wish.  We could
them all in an array for all we care.  There won't need to be any
synchronization unless we replace an entry.  We can further increase the
speed of the whole system.

For systems that _have_ to resolve components at run time like Cocoon,
would be a godsend.

>     /**
>      * Keep current method, basically making the call to
>      * createRequest internal. Also means these changes can probably
>      * be done somewhere in a future avalon 4 release as no existing
>      * functionality is removed or changed.
>      * Note that the CM could still do some smart caching of the
>      * generated Request objects internally.
>      */
>     Object lookup( String role ) throws RuntimeException;

To maintain compatibility it would be ComponentException--not

Also, we don't want to declare the throwing of RuntimeExceptions because
then you lose the advantage of not being forced to use a

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

View raw message