You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Peter Donald <pe...@apache.org> on 2002/06/02 08:12:37 UTC

Re: ContainerManager and Sub-containers

On Wed, 29 May 2002 21:09, Leo Sutic wrote:
> > From: Peter Donald [mailto:peter@apache.org]
> >
> > Looks very similar to phoenixs layout with a few name changes ;)
>
> Very - and since you've been at it a while longer than I: Do you
> handle component/hint mappings, or just role mappings? That is,
> can I specify that for Role X, selected with Hint Y, A should get
> U, and B should get V? Or do you just allow the remapping to
> work on roles?

Phoenix just does Role mappings at this stage though just recently something 
similar to hints has come up. Basically any time there is a Component A that 
depends on a component B where B is contained within C. 

Examples include;

Depending on specific ThreadPool inside ThreadManager, SocketFactory inside 
SocketManager, Component with hint X inside ComponentSelector, Corba service 
inside Corba ORB yada yada yada

Not really sure how to handle it at this stage. Going to trya few things next 
weekend but nothing jumps out at me right now.

-- 
Cheers,

Peter Donald
*------------------------------------------------*
| Trying is the first step to failure.           |
|   So never try, Lisa  - Homer Jay Simpson      |
*------------------------------------------------* 


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: ContainerManager and Sub-containers

Posted by Stephen McConnell <mc...@osm.net>.

Peter Donald wrote:

>On Sun, 2 Jun 2002 19:38, Leo Sutic wrote:
>  
>
>>>Depending on specific ThreadPool inside ThreadManager,
>>>SocketFactory inside
>>>SocketManager
>>>      
>>>
>>Hmm. Just guessing, but a role -> role + hint mapping could do it.
>>Let SocketFactory implement ComponentSelector and lookup
>>SocketFactory.ROLE.
>>This gets mapped to a lookup (SocketManager.ROLE) and a select (hint).
>>
>>I think the key is to have the second lookup (to find the component B
>>that is contained in C) standardized via a interface.
>>    
>>
>
>Personally I think the exact opposite ;) 
>
>I HATE the ComponentSelector interface and think it is a huge mistake to use 
>it. If the ComponentSelector is simply access to a category of avalon 
>components then I can't see why you can't depend on/lookup a component 
>directly. 
>
>ie Consider case where you look up selector with SocketManager.ROLE then look 
>up SocketFactory component using "ssl" hint. Why could you not instead lookup 
>the ssl factory directly via SocketFactory.ROLE + "/ssl". 
>  
>
+1

>Much easier to do dependency checking, much easier for component implementer 
>and gives the assembler much more choice in assembling the system.
>
>  
>

-- 

Stephen J. McConnell

OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: ContainerManager and Sub-containers

Posted by Peter Royal <pr...@apache.org>.
On Tuesday 04 June 2002 09:32 am, Berin Loritsch wrote:
> This will perform better than strings will in high performance
> or throughput situations, and it is easy to use.  Let's say the
> container stores the Components in an array (or an ArrayList)
> instead of a hashmap.  With this Request object, it is possible.
> A map would be used to find the Request object, done during
> initialization.  The list would be used to serve the components.

I like it! Request could maybe be renamed to Token or something similar, but 
conceptually what you have outlined looks good.
-pete
 

-- 
peter royal -> proyal@apache.org

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Gregory Steuck <gr...@nest.cx>.
>>>>> "Leo" == Leo Simons <le...@apache.org> writes:

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

    Leo> 1 - don't use String (use int, long, char[]) 2 - cache
    Leo> Strings (define Strings as early as possible, minimise
    Leo> operations on String, cache operations on String)

    Leo> the advantage of 1 is a cleaner (smaller) implementation.

Disadvantage is being bound to a particular primitive type that you
can't possibly extend or change. Request implementation on the other
hand changes the underlying mechanisms without affecting the user.
Even String is bad enough for it is final.

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Berin Loritsch <bl...@apache.org>.
> From: Stephen McConnell [mailto:mcconnell@osm.net] 
> 
> Leo Sutic wrote:
> 
> >>From: Peter Donald [mailto:peter@apache.org]
> >>
> >>Lets see - I can think of two reasons ;)
> >>    
> >>
> >
> >One reason will be enough - as long as it has to do with 
> scalability, 
> >which was what you claimed was the problem. ;)
> >
> >Your first reason is a design decision - does a component manager 
> >manage resources, or is it a directory lookup? I go for the 
> former, you 
> >go for the latter. The nice thing about Avalon, IMO, is that 
> it isn't 
> >just a naming lookup - I have JNDI for that.
> >
> 
> I look at the resulting divergence - you have the "release" operation 
> which is only applicable in the case of pooled resources and yet the 
> semantics of a pool are undefined at that level or abstraction.  The 
> default implementation of release in CM and SM are empty - 
> perhaps this 
> suggests something - its an operation that is inconsitent with the 
> abstraction supported by CM/SM.  Would it not be more appropriate for 
> "release" to be moved up to another interface where the concepts of a 
> pool is defined?  
> 
> But we've had this discussion before ;-).


Reminder to everyone:

The reason for the release() method was largely in part due to the
design
decisions of the Pool mechanism at the time.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: ContainerManager and Sub-containers

Posted by Stephen McConnell <mc...@osm.net>.

Leo Sutic wrote:

>>From: Peter Donald [mailto:peter@apache.org] 
>>
>>Lets see - I can think of two reasons ;)
>>    
>>
>
>One reason will be enough - as long as it has to do with scalability,
>which was what you claimed was the problem. ;)
>
>Your first reason is a design decision - does a component manager
>manage resources, or is it a directory lookup? I go for the former,
>you go for the latter. The nice thing about Avalon, IMO, is that it
>isn't just a naming lookup - I have JNDI for that.
>

I look at the resulting divergence - you have the "release" operation 
which is only applicable in the case of pooled resources and yet the 
semantics of a pool are undefined at that level or abstraction.  The 
default implementation of release in CM and SM are empty - perhaps this 
suggests something - its an operation that is inconsitent with the 
abstraction supported by CM/SM.  Would it not be more appropriate for 
"release" to be moved up to another interface where the concepts of a 
pool is defined?  

But we've had this discussion before ;-).

Cheers, Steve,

-- 

Stephen J. McConnell

OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org] 
>
> Design Decision:
> 
> THE Component Manager IS A LOOKUP MECHANISM. PERIOD.
> 
> The ECM is a HACK.  It has poluted the minds of all who use 
> it into thinking that there is no difference, or very little 
> difference between a lookup mechanism and a container!  The 
> ECM merged the two in a monolithic design, and it is a HACK.
 
Berin,

please clarify yourself - I note that Fortress share the same
design where the AbstractContainer manages resources *and*
provides a ComponentManager interface via an internal class.
Do you object to ECM implementing the CM interface directly
instead of doing like Fortress, or?

Given your comments about the pool - that release() was just
a design decision based on the pool implementation - and that
we've sort of agreed that if the container does any kind
of pooling, then the ComponentManager interface must
have a release() method or some other way of letting the 
client indicate that it is done using the object, is
it not then your opinion that pooling of components should
not be done by the container? (ComponentManager only used
for lookup -> no release() method -> no pooling)

/LS



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Berin Loritsch <bl...@apache.org>.
> From: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com] 
> 
> > From: Peter Donald [mailto:peter@apache.org]
> >
> > Lets see - I can think of two reasons ;)
> 
> One reason will be enough - as long as it has to do with 
> scalability, which was what you claimed was the problem. ;)
> 
> Your first reason is a design decision - does a component 
> manager manage resources, or is it a directory lookup? I go 
> for the former, you go for the latter. The nice thing about 
> Avalon, IMO, is that it isn't just a naming lookup - I have 
> JNDI for that.

Design Decision:

THE Component Manager IS A LOOKUP MECHANISM. PERIOD.

The ECM is a HACK.  It has poluted the minds of all who use it
into thinking that there is no difference, or very little
difference between a lookup mechanism and a container!  The ECM
merged the two in a monolithic design, and it is a HACK.

ComponentManager == Lookup Mechanism
Container == resource management

DO NOT MIX THE TWO.

This is something that Peter and I agree on wholeheartedly.  It
is also the original vision of the CM.

JNDI == expensive lookup mechanism, complex to implement
CM == inexpensive lookup mechanism, easy to implement



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Leo Sutic <le...@inspireinfrastructure.com>.
> From: Peter Donald [mailto:peter@apache.org] 
>
> Lets see - I can think of two reasons ;)

One reason will be enough - as long as it has to do with scalability,
which was what you claimed was the problem. ;)

Your first reason is a design decision - does a component manager
manage resources, or is it a directory lookup? I go for the former,
you go for the latter. The nice thing about Avalon, IMO, is that it
isn't just a naming lookup - I have JNDI for that.

Your second reason is not something I can accept before being convinced
that your first reason is correct.
 
/LS


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Peter Donald <pe...@apache.org>.
At 10:06 AM 6/6/2002 +0200, you wrote:
>As for the directory-should-not-do-pooling: If I put a DataSource in the
>directory, I do:
>
>     Connection conn = ((DataSource) manager.lookup
>(DataSource.ROLE)).getConnection ();
>
>Now since I'll always want the connection, why not just give me the
>connection
>right away?
>
>     Connection conn = (Connection) manager.lookup (Connection.ROLE);

Lets see - I can think of two reasons ;)

* Your cease to separate directory and resource management code and thus 
you end up with a ugly "release()" method on your directory interface 
(despite the fact that only a handful of people ever use it).
* You get people who complain that ServiceManager not fast enough and then 
want the rest of us to add in extra ugly code so they can continue to 
misuse the interface





--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Leo Simons [mailto:leosimons@apache.org] 
> 
> > > > However, for most people it is just quicker to do this:
> > > > 
> > > > manager.lookup (Generator.ROLE + "/fooo");
> > > 
> > > make sure you tell everyone you can influence not to! We
> > > really need that "best practices" stuff =)
> > 
> > It gets tiring.  Why not just not make it possible?
> 
> why, to improve the world, of course!
> 
> > Rewritten because all Requests were handled in the compose() method:
> 
> here it is: a-hah! Make it a contract that Request can only 
> ever be created during compose() (pre-init()) and there you 
> go: no more misuse.

But then you can not create a Request based on (for example) the
incoming
HTTP request (as in Cocoon). Unless you prepopulate a HashMap or
something
with all possible requests.
 
I'm all for Berin's query object approach - the only thing lacking is
the
neatness of a 

           lookup( ISeeExactlyWhatInterfaceImGetting.ROLE );

I do not consider going from:

  MyComponent myComponent = null;
  try {
    myComponent = (MyComponent) manager.lookup (MyComponent.ROLE);
    // Do stuff that may throw Exception (which is the typical case in
my experience)
  } catch (ComponentException ce) {
    // Ugh.
  } catch (Exception e) {
    // Ugh.
  } finally {
    manager.release (myComponent);
  }

to:

  MyComponent myComponent = manager.lookup (myComponentRequest);
  try {
    // Do stuff that may throw exceptions (which is the typical case in
my experience)
  } catch (Exception ce) {
    // Awwww...
  } finally {
    manager.release (myComponent);
  }

a killer feature, but getting those ComponentSelectors out of my code
makes it worth 
the extra instance variable and stuff.

What I do consider a

        --~~==¤¤**++:::::>>> KILLER FEATURE <<<:::::++**¤¤==~~--

would be the incorporation of Peter's Phoenix 

    <component ...>
        <provide .../>
    </component>

way of linking components as described here:

    http://marc.theaimsgroup.com/?l=avalon-dev&m=102266947408779&w=2

into Fortress. Remember, in the ComponentManager spec., a component
should *only* be given those components it needs to work, not any other!

Having <provide/> would not only enable that, but also solve the initial
problem:

    http://marc.theaimsgroup.com/?l=avalon-dev&m=102260094419459&w=2

    Component A requires a component with role B. For example, a
QueryEngine
    requires a DBConnectionPool.

    Now, we add component C that also requires a component with role B.
    Like, a Logger requires a DBConnectionPool to log into a database.

    Stuffing A and C into the same Container so that they get the same
CM
    makes it necessary to have them either use the same implmentation of
B
    or use a ComponentSelector. But then they have to be written to use
a
    CS.

which was described in a different way by Marc Scheier here:

    http://marc.theaimsgroup.com/?l=avalon-dev&m=102312257108468&w=2


                           (Killer Feature End)


As for the directory-should-not-do-pooling: If I put a DataSource in the
directory, I do:

    Connection conn = ((DataSource) manager.lookup
(DataSource.ROLE)).getConnection ();

Now since I'll always want the connection, why not just give me the
connection
right away?

    Connection conn = (Connection) manager.lookup (Connection.ROLE);

I do not see the scalability problem here. With the DataSource approach
I just see
it as not quite as clear when reading the code just what is happening.
The lookup
should, IMO, be for "what I want to use" not "what I want in order to
get what I 
want to use". (This is my problem with exposing the ComponentSelector
interface - 
I want the component, and I want it in *one* lookup. Not some two-stage
process.)

A few notes on scalability - with the BucketMap the thread conflicts
inside the 
container are basically eliminated. Any threading issues will then be in
the pooling
code - making access via DataSource (which must have a pool) as
efficient as access
through a PoolableComponentHandler or equivalent (which has a pool).

/LS


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Leo Simons <le...@apache.org>.
> > > However, for most people it is just quicker to do this:
> > > 
> > > manager.lookup (Generator.ROLE + "/fooo");
> > 
> > make sure you tell everyone you can influence not to! We 
> > really need that "best practices" stuff =)
> 
> It gets tiring.  Why not just not make it possible?

why, to improve the world, of course!

> Rewritten because all Requests were handled in the compose() method:

here it is: a-hah! Make it a contract that Request can only ever be
created during compose() (pre-init()) and there you go: no more misuse.

> > You think there are many cases where string creation or 
> > string hashing are the bottleneck for a system that needs 
> > performance. You propose to use a request object for the CM, 
> > basically a container for a long, to solve this. The request 
> > object is then retrieved, using string creation and string 
> > hashing, from the CM.
> 
> Not to meantion the protection that a Request from one container
> isn't guaranteed to work in another container.

ah. Something worth mentioning, that is =)

> > I think the bottleneck is usually elsewhere. I propose to 
> > leave the responsibility for optimisation outside of the 
> > ComponentManager interface.
> 
> Any time you call toString(), it is a very expensive routine.
> Called several times in the critical path, and it can easily
> account for 30% of your processing time.

I still think component lookup is usually not the bottleneck, the key
phrase being "critical path". This is perhaps because I know how to
write avalon-based software while avoiding these bottlenecks (without
knowing that I avoid anything), or don't know how to write software with
other bottlenecks, or perhaps because it really is uncommon for this
problem.

> > did I miss something?
> 
> Of course you did.  You are also missing the fact that pulling
> a component from an array is quicker than pulling one from a hash.
> You also are forgetting how hashes work.

Nah, just have never found them to be a problem. Missed two other points
though...

conclusion: Leo's seen the light and will not vote -1 =)

g'night,

- Leo



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Berin Loritsch <bl...@apache.org>.
> 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");
> 
> make sure you tell everyone you can influence not to! We 
> really need that "best practices" stuff =)

It gets tiring.  Why not just not make it possible?


> > The purpose of the Generator.ROLE + "/foo" is not to arbitrarily 
> > select between several implementations of a Generator, but 
> to further 
> > define the _ROLE_.
> 
> While not the purpose, I can see people misusing it in that way.

Exactly.  Which means that the CM needs a better query for the
instance of the component--which we can provide with the interface
I proposed.

> basically, you substitute exception handling for a test 
> against "null". This is not an advantage.

Sure it is.  The real benefit is when you have multiple
components you have to work with--and they are mutually
exclusive.

That "null" is to remove the need for the hasComponent()
method--which is obvious.  We haven't reached critical
code yet, so no exception is necessary.

> 
> good:
> 
> doAction() throws ActionException
> {
> 	ActionHandler handler = null;
> 	try
> 	{
> 		final ActionHandler handler =
> 			(ActionHandler)m_manager.lookup(
> 				ActionHandler.ROLE );
> 		final Object result = handler.doSomething();
> 		m_manager.release( handler );
> 		return result;
> 	}
> 	catch( ComponentException ce )
> 	{
> 		getLogger.error("Missing Component", ce);
> 		throw new ActionException("Sorry!", ce);
> 	}
> 	// no need to release handler if a ComponetException occurs
> }

Rewritten because all Requests were handled in the compose() method:

doAction() throws ActionException
{
    ActionHandler handler =
(ActionHandler)m_manager.lookup(m_handlerReq);
    final Object result = handler.doSomething();
    m_manager.release( handler );
    return result;

    // no need to worry about missing components because we took
    // care of that in the compose() method!
}

<snip>both misapplications</snip>

> Exceptions are _good_. try/catch is better than if/else in 
> cases like this.

See the comment.  You obviously didn't see my example in the
first message I posted.  The Request objects are able to be
cached.

> 
> > We saved three lines of code, and increased readability and 
> > comprehensibility of the code at the same time!
> 
> I disagree. See samples.

In the way that I wrote the method, we saved 8 lines.  It is
obvious that the component is required.  We don't have to verify
its existance every time we request the the component.  We only
have to reuse the request object!

Are you getting where I am coming from?


> >  By three lines of code, I am counting
> > every
> > 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 you have a new bracket).  We even saved here.
> 
> The exception-based method has two (one for try, one for 
> catch), the non-exception-based string method has one, and 
> the request-object-based method has one.

And one for finally.

> > > 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 
> > different threads.  The ECM is one major source of thread 
> contention 
> > issues. Fortress
> > is proof that by removing as many chances for thread contention as
> > possible
> > dramatically increases the speed in which you can resolve requests.
> > 
> > Using the Request based component resolution, we gain 
> further benefits 
> > by the ability to arange the components in any fashion we wish.  We 
> > could put
> > 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.
> 
> Is this not possible in a way completely internal to the CM?

Not with strings as keys!

> > >     /**
> > >      * 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 
> > RuntimeException.
> 
> gotcha. What I ment.
> 
> What I see:
> 
> You think there are many cases where string creation or 
> string hashing are the bottleneck for a system that needs 
> performance. You propose to use a request object for the CM, 
> basically a container for a long, to solve this. The request 
> object is then retrieved, using string creation and string 
> hashing, from the CM.

Not to meantion the protection that a Request from one container
isn't guaranteed to work in another container.

> 
> I think the bottleneck is usually elsewhere. I propose to 
> leave the responsibility for optimisation outside of the 
> ComponentManager interface.

Any time you call toString(), it is a very expensive routine.
Called several times in the critical path, and it can easily
account for 30% of your processing time.


> If the request object is not cached by the user, there is 
> little performance gain. If the user is smart enough to cache 
> the request object, he is probably also smart enough to cache 
> the lookup string and the requested component, meaning there 
> is no bottleneck.
> 
> did I miss something?

Of course you did.  You are also missing the fact that pulling
a component from an array is quicker than pulling one from a hash.
You also are forgetting how hashes work.

Take a look at the BucketMap for clarity on the subject.  To make
a long story short, a HashMap truncates the hashCode() value to
make it fit inside an internal array (I am sure there are different
uses, but bear with me).  If the hash algorithm is good, it will
spread the entries fairly even within the array.  However, if you
have 1000 components and 100 entries in an array, we still have
at least 10 nodes in each array entry.  The hashmap has to iterate
through those nodes to find an exact match.  That means calling
equals() on each key.

What is faster, comparing strings or longs?

"org.apache.avalon.excalibur.datasource.DatasourceComponent/default"
"org.apache.avalon.excalibur.datasource.DatasourceComponent/special"

56
57

Since many components have the first part the same, we don't see a
difference until we have iterated over ~59 characters!

I am suggesting moving the hashing part of component resolution
to the initialization of a component rather than the runtime.
It takes almost no time at all for a container to call:

return m_components[req.key];

String operations and converting StringBuffers to Strings (what happens
implicitly when you operate on XYZ + "foo") are expensive--esp. when
many characters are the same.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Leo Simons <le...@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");

make sure you tell everyone you can influence not to! We really need
that "best practices" stuff =)

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

While not the purpose, I can see people misusing it in that way.

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

Ehm, it merges the two solutions.

> Comparison (the component may not exist):
> 
> OLD CM
> ------
> TestComponent myComp = null;
> 
> try
> {
>     myComp = (TestComponent) manager.lookup( TestComponent.ROLE );
> 
>     myComp.doSomething();
> }
> catch (ComponentException ce)
> {
>     getLogger().error("Missing component", ce);
> }
> finally
> {
>     if (null != myComp) manager.release( myComp );
> }
> 
> 
> NEW CM
> ------
> Request req = manager.createRequest( TestComponent.ROLE );
> 
> if (null == req)
> {
>     getLogger().error("Missing component");
> }
> else
> {
>     TestComponent myComp = manager.lookup( req ); // guaranteed to be
> there
>     myComp.doSomething();
>     manager.release(myComp);
> }

basically, you substitute exception handling for a test against "null".
This is not an advantage.

good:

doAction() throws ActionException
{
	ActionHandler handler = null;
	try
	{
		final ActionHandler handler =
			(ActionHandler)m_manager.lookup(
				ActionHandler.ROLE );
		final Object result = handler.doSomething();
		m_manager.release( handler );
		return result;
	}
	catch( ComponentException ce )
	{
		getLogger.error("Missing Component", ce);
		throw new ActionException("Sorry!", ce);
	}
	// no need to release handler if a ComponetException occurs
}

as opposed to:

doAction()
{
	final ActionHandler handler = (ActionHandler)m_manager.lookup(
			ActionHandler.ROLE ); /* no reason we can't
		drop the exception in this method if we want */
	if( null == handler )
	{
		getLogger.error("Missing Component");
		return null;
		// no need to release handler if there is none
	}

	final Object result = handler.doSomething();
	m_manager.release( handler );
	return result;
}

or:

doAction()
{
	final Request request = m_manager.createRequest(
			ActionHandler.ROLE );
	if( null == request )
	{
		getLogger.error("Missing Component");
		return null;
	}
	final ActionHandler handler = (ActionHandler)m_manager.lookup(
			ActionHandler.ROLE );

	final Object result = handler.doSomething();
	m_manager.release( handler );
	return result;
}


Exceptions are _good_. try/catch is better than if/else in cases like
this.

> We saved three lines of code, and increased readability and
> comprehensibility
> of the code at the same time!

I disagree. See samples.

>  By three lines of code, I am counting
> every
> 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
> you
> have a new bracket).  We even saved here.

The exception-based method has two (one for try, one for catch), the
non-exception-based string method has one, and the request-object-based
method has one.

However, I think complexity doesn't really increase when using
exceptions.

The use of the request object does not reduce complexity, though.

> > 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
> different
> threads.  The ECM is one major source of thread contention issues.
> Fortress
> is proof that by removing as many chances for thread contention as
> possible
> dramatically increases the speed in which you can resolve requests.
> 
> Using the Request based component resolution, we gain further benefits
> by
> the ability to arange the components in any fashion we wish.  We could
> put
> 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.

Is this not possible in a way completely internal to the CM?

> >     /**
> >      * 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
> RuntimeException.

gotcha. What I ment.

What I see:

You think there are many cases where string creation or string hashing
are the bottleneck for a system that needs performance. You propose to
use a request object for the CM, basically a container for a long, to
solve this.
The request object is then retrieved, using string creation and string
hashing, from the CM.

I think the bottleneck is usually elsewhere. I propose to leave the
responsibility for optimisation outside of the ComponentManager
interface.

If the request object is not cached by the user, there is little
performance gain. If the user is smart enough to cache the request
object, he is probably also smart enough to cache the lookup string and
the requested component, meaning there is no bottleneck.

did I miss something?

- Leo



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Berin Loritsch <bl...@apache.org>.
> 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
persist
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):

OLD CM
------
TestComponent myComp = null;

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

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


NEW CM
------
Request req = manager.createRequest( TestComponent.ROLE );

if (null == req)
{
    getLogger().error("Missing component");
}
else
{
    TestComponent myComp = manager.lookup( req ); // guaranteed to be
there
    myComp.doSomething();
    manager.release(myComp);
}


We saved three lines of code, and increased readability and
comprehensibility
of the code at the same time!  By three lines of code, I am counting
every
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
you
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
different
threads.  The ECM is one major source of thread contention issues.
Fortress
is proof that by removing as many chances for thread contention as
possible
dramatically increases the speed in which you can resolve requests.

Using the Request based component resolution, we gain further benefits
by
the ability to arange the components in any fashion we wish.  We could
put
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,
this
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
RuntimeException.

Also, we don't want to declare the throwing of RuntimeExceptions because
then you lose the advantage of not being forced to use a
try/catch/finally
block.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Leo Simons <le...@apache.org>.
> > > > I HATE the ComponentSelector interface and think it is a huge 
> > > > mistake to use it. If the ComponentSelector is simply access to a 
> > > > category of avalon components then I can't see why you 
> > can't depend 
> > > > on/lookup a component
> > > > directly.
> > >
> > > Keep in mind the purpose of the Selector/Manager relationship.
> > 
> > I recall - one of the time I wished I had kept arguing ;)
> 
> :)  Maybe it is something we can address for the next version of
> Avalon framework....  In that case, I would like to drag Stefano
> into the midst of the discussion--he's pretty smart.
> 
> I personally want to remove the necessity of string resolution,
> but I haven't been able to come up with something that is happy
> for all of us involved.  Strings are the major bottleneck of
> Avalon right now.  Esp. for something like Cocoon where we we can
> expect over 1000 requests per second in a heavy traffic site
> (that translates to 86,400,000 hits in a day) and components
> are resolved at runtime.  That's a lot of string opperations!
> 
> That's a lot of Generator.ROLE + "/fooo"!

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"!;

> But that is another subject entirely.

quite correct. I'll shut up.

> > > The components available for Generation, Transformation,
> > > or Serialization are many.  Plus it is hard to determine 
> > what should 
> > > be the actual mapping to the specified component.  For example:
> > >
> > > Generator.ROLE + "/file"
> > > Generator.ROLE + "/stream"
> > > Generator.ROLE + "/foo"
> > >
> > > Truth be told, the File and Stream options can both be used 
> > to get the 
> > > same results....
> > 
> > 
> > dont see relevance of above ?
> 
> Maybe not, but their implementations overlap.
<snip>
> 
> 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?

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

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

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

>  Strings have the limitation of
> being
> expensive to match, and expensive to hash.  Especially when most of the
> string is the same.  As a result, we can solve the problem like this:
> 
> /**
>  * Avalon 5 interface, so I can reuse the component manager name.
>  */
> public interface ComponentManager
> {
>     /**
>      * These methods create a Request object for the CM.  It will
>      * return <code>null</code> if the component does not exist.
>      */
>     Request createRequest( String role );
>     Request createRequest( String role, Object hint );
> 
>     /**
>      * No need for exceptions because the Request object originates
>      * from the ComponentManager.  The only issue that might come up
>      * is a Request object from a different CM--in that case a
>      * RuntimeException is accpetable.
>      */
>     Object lookup( Request role );

    /**
     * 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;

> 
>     /**
>      * Still can't be convinced that this isn't necessary as long as
>      * we have pooled components.
>      */
>     void release(Object component );
> }

g'night,

- Leo



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Berin Loritsch <bl...@apache.org>.
> From: Peter Donald [mailto:peter@apache.org] 
> 
> On Mon, 3 Jun 2002 22:30, Berin Loritsch wrote:
> > > From: Peter Donald [mailto:peter@apache.org]
> > >
> > > > I think the key is to have the second lookup (to find the
> > >
> > > component B
> > >
> > > > that is contained in C) standardized via a interface.
> > >
> > > Personally I think the exact opposite ;)
> > >
> > > I HATE the ComponentSelector interface and think it is a huge 
> > > mistake to use it. If the ComponentSelector is simply access to a 
> > > category of avalon components then I can't see why you 
> can't depend 
> > > on/lookup a component
> > > directly.
> >
> > Keep in mind the purpose of the Selector/Manager relationship.
> 
> I recall - one of the time I wished I had kept arguing ;)

:)  Maybe it is something we can address for the next version of
Avalon framework....  In that case, I would like to drag Stefano
into the midst of the discussion--he's pretty smart.

I personally want to remove the necessity of string resolution,
but I haven't been able to come up with something that is happy
for all of us involved.  Strings are the major bottleneck of
Avalon right now.  Esp. for something like Cocoon where we we can
expect over 1000 requests per second in a heavy traffic site
(that translates to 86,400,000 hits in a day) and components
are resolved at runtime.  That's a lot of string opperations!

That's a lot of Generator.ROLE + "/fooo"!

But that is another subject entirely.


> > The selector is much better or more elegant when we have something 
> > like Cocoon.
> 
> I sooooooooooooo disagree ;) The only person it is "elegant" 
> for is the 
> container writer - a very small % of overall cocoon developers.

Ok.  I'll give you that.  The difference between the selector and
the appended name is largely like EJB binding to a JNDI context.

J2EE spec specifies that the components are mapped to the following
root (or something close):

java:/comp/mycomp
java:/comp/mycomp/first
java:/comp/mycomp/second

All of those are valid binding locations.  The mycomp would be like
the default implementation of "mycomp" and "/first" and "/second" would
be the more specific implementations.

What you are advocating is like that.  (BTW, I was moving toward a
default impl in Fortress).


> > The components available for Generation, Transformation,
> > or Serialization are many.  Plus it is hard to determine 
> what should 
> > be the actual mapping to the specified component.  For example:
> >
> > Generator.ROLE + "/file"
> > Generator.ROLE + "/stream"
> > Generator.ROLE + "/foo"
> >
> > Truth be told, the File and Stream options can both be used 
> to get the 
> > same results....
> 
> 
> dont see relevance of above ?

Maybe not, but their implementations overlap.  The Stream version would
be able to grab info from any stream--but at the cost of not being
cacheable.
The file version is cacheable, but is limited to files.

So the container could theorhetically replace one for the other
depending
on the URI.

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.

> hmm then lets go with generators then. Lets say you have 10 generators
> 
> Generator.ROLE selects the default component in role while 
> Generator + "/X" 
> selects the X generators - wheres e problem ?
> 
> >
> > > Much easier to do dependency checking, much easier for component 
> > > implementer and gives the assembler much more choice in 
> assembling 
> > > the system.
> >
> > And the more complex ways are having the container take 
> care of it all 
> > for you.
> 
> explain.

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

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.  Strings have the limitation of
being
expensive to match, and expensive to hash.  Especially when most of the
string is the same.  As a result, we can solve the problem like this:

/**
 * Avalon 5 interface, so I can reuse the component manager name.
 */
public interface ComponentManager
{
    /**
     * These methods create a Request object for the CM.  It will
     * return <code>null</code> if the component does not exist.
     */
    Request createRequest( String role );
    Request createRequest( String role, Object hint );

    /**
     * No need for exceptions because the Request object originates
     * from the ComponentManager.  The only issue that might come up
     * is a Request object from a different CM--in that case a
     * RuntimeException is accpetable.
     */
    Object lookup( Request role );

    /**
     * Still can't be convinced that this isn't necessary as long as
     * we have pooled components.
     */
    void release(Object component );
}

public final class Request
{
     public final Object origination;
     public final long  key;

     public Request( Object parent, long key )
     {
         origination = parent;
         this.key = key;
     }

     public long hashCode()
     {
         return key;
     }

     public boolean equals( Object other )
     {
         if ( ! other instanceOf Request ) return false;

         Request test = (Request) other;

         if ( other.key != key ) return false;
         if ( other.origination != origination) return false;

         return true;
     }
}

This will perform better than strings will in high performance
or throughput situations, and it is easy to use.  Let's say the
container stores the Components in an array (or an ArrayList)
instead of a hashmap.  With this Request object, it is possible.
A map would be used to find the Request object, done during
initialization.  The list would be used to serve the components.

/**
 * example lookup
 */
public Object lookup( Request role )
{
    if ( role.origination != this )
        throw new InvalidRequestException; // extends RuntimeException

    return m_componentList.get(role.key);
}

/**
 * Example createRequest
 */
public Request createRequest( String role )
{
    return createRequest( role, null );
}

public Request createRequest( String role, Object hint )
{
    if ( null == role ) return null;

    Map specificMap = m_roles.get( role );

    if ( null == specificMap ) return null;

    Object test = hint;
    Request req = null;

    if ( null == test ) test = "default";

    req = (Request)specificMap.get( test );

    if ( null == component && ! test.equals( "default" ) )
    {
        req = (Request)specificMap.get( "default" );
    }

    return req;
}


An example component using it would look like this:

/**
 * Component Impl.
 */
public final class MyComponent implements Composable
{
    Request m_required = null;
    Request m_optional = null;
    ComponentManager m_manager = null;

    public void compose( ComponentManager manager )
        throws ComponentException;
    {
        m_manager = manager;
        m_required = manager.createRequest( EchoComponent.ROLE );
        m_optional = manager.createRequest( I18nComponent.ROLE,
"XML-bundle" );

        if ( null == m_required ) throw new ComponentException("Missing
component");
    }

    public return processRequest( String message )
    {
        EchoComponent echo = (EchoComponent)m_manager.lookup( m_required
);
        String newMessage = echo.echoMessage( message );

        if ( null != m_optional )
        {
            I18nComponent trans = (I18nComponent)m_manager.lookup(
m_optional );
            newMessage = trans.translateMessage( newMessage );
            m_manager.release( trans );
        }

        m_manager.release( echo );
        return newMessage;
    }
}


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: ContainerManager and Sub-containers

Posted by Peter Donald <pe...@apache.org>.
On Mon, 3 Jun 2002 22:30, Berin Loritsch wrote:
> > From: Peter Donald [mailto:peter@apache.org]
> >
> > > I think the key is to have the second lookup (to find the
> >
> > component B
> >
> > > that is contained in C) standardized via a interface.
> >
> > Personally I think the exact opposite ;)
> >
> > I HATE the ComponentSelector interface and think it is a huge
> > mistake to use
> > it. If the ComponentSelector is simply access to a category of avalon
> > components then I can't see why you can't depend on/lookup a
> > component
> > directly.
>
> Keep in mind the purpose of the Selector/Manager relationship.

I recall - one of the time I wished I had kept arguing ;)

> The selector is much better or more elegant when we have something
> like Cocoon. 

I sooooooooooooo disagree ;) The only person it is "elegant" for is the 
container writer - a very small % of overall cocoon developers.

> The components available for Generation, Transformation,
> or Serialization are many.  Plus it is hard to determine what should
> be the actual mapping to the specified component.  For example:
>
> Generator.ROLE + "/file"
> Generator.ROLE + "/stream"
> Generator.ROLE + "/foo"
>
> Truth be told, the File and Stream options can both be used to get the
> same results....


dont see relevance of above ?

> So how do we choose the suffix safely?  The Selector is better here.

exactly how is it better? I can't see much difference at all.

> > ie Consider case where you look up selector with
> > SocketManager.ROLE then look
> > up SocketFactory component using "ssl" hint. Why could you
> > not instead lookup
> > the ssl factory directly via SocketFactory.ROLE + "/ssl".
>
> In this case, it might be just better this way.  You have two options:
> SSL and no SSL.


hmm then lets go with generators then. Lets say you have 10 generators

Generator.ROLE selects the default component in role while Generator + "/X" 
selects the X generators - wheres e problem ?

>
> > Much easier to do dependency checking, much easier for
> > component implementer
> > and gives the assembler much more choice in assembling the system.
>
> And the more complex ways are having the container take care of it
> all for you.

explain.

-- 
Cheers,

Peter Donald
------------------------------------------------
| We shall not cease from exploration, and the |
|  end of all our exploring will be to arrive  |
|  where we started and know the place for the |
|            first time -- T.S. Eliot          |
------------------------------------------------



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Berin Loritsch <bl...@apache.org>.
> From: Peter Donald [mailto:peter@apache.org] 
> 
> > I think the key is to have the second lookup (to find the 
> component B 
> > that is contained in C) standardized via a interface.
> 
> Personally I think the exact opposite ;) 
> 
> I HATE the ComponentSelector interface and think it is a huge 
> mistake to use 
> it. If the ComponentSelector is simply access to a category of avalon 
> components then I can't see why you can't depend on/lookup a 
> component 
> directly. 

Keep in mind the purpose of the Selector/Manager relationship.

The selector is much better or more elegant when we have something
like Cocoon.  The components available for Generation, Transformation,
or Serialization are many.  Plus it is hard to determine what should
be the actual mapping to the specified component.  For example:

Generator.ROLE + "/file"
Generator.ROLE + "/stream"
Generator.ROLE + "/foo"

Truth be told, the File and Stream options can both be used to get the
same results....

So how do we choose the suffix safely?  The Selector is better here.


> ie Consider case where you look up selector with 
> SocketManager.ROLE then look 
> up SocketFactory component using "ssl" hint. Why could you 
> not instead lookup 
> the ssl factory directly via SocketFactory.ROLE + "/ssl". 

In this case, it might be just better this way.  You have two options:
SSL and no SSL.


> Much easier to do dependency checking, much easier for 
> component implementer 
> and gives the assembler much more choice in assembling the system.


And the more complex ways are having the container take care of it
all for you.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Leo Sutic <le...@inspireinfrastructure.com>.
> From: Peter Donald [mailto:peter@apache.org] 
> 
> On Sun, 2 Jun 2002 19:38, Leo Sutic wrote:
> > > Depending on specific ThreadPool inside ThreadManager, 
> SocketFactory 
> > > inside SocketManager
> >
> > Hmm. Just guessing, but a role -> role + hint mapping could 
> do it. Let 
> > SocketFactory implement ComponentSelector and lookup 
> > SocketFactory.ROLE. This gets mapped to a lookup 
> (SocketManager.ROLE) 
> > and a select (hint).
> >
> > I think the key is to have the second lookup (to find the 
> component B 
> > that is contained in C) standardized via a interface.
> 
> Personally I think the exact opposite ;) 
> 
> I HATE the ComponentSelector interface and think it is a huge 
> mistake to use 
> it.

I pretty much hate it too, but if the interface was never exposed to
the client - that is, the second lookup (to find B in the example)
is done by the container and all the client sees is a
ComponentManager.lookup - 
then I consider it OK. The only reason for keeping the CS interface
would be to let components like C implement it in order to make
the lookup possible.

> If the ComponentSelector is simply access to a category of avalon 
> components then I can't see why you can't depend on/lookup a 
> component 
> directly.

Of course you can - but with CS you can select on other hints than
a string. Of course you can do the Whatever -> String conversion
and then do a straight lookup as you say, but it may make more sense
to  encapsulate it in a selector.
 
/LS


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: ContainerManager and Sub-containers

Posted by Peter Donald <pe...@apache.org>.
On Sun, 2 Jun 2002 19:38, Leo Sutic wrote:
> > Depending on specific ThreadPool inside ThreadManager,
> > SocketFactory inside
> > SocketManager
>
> Hmm. Just guessing, but a role -> role + hint mapping could do it.
> Let SocketFactory implement ComponentSelector and lookup
> SocketFactory.ROLE.
> This gets mapped to a lookup (SocketManager.ROLE) and a select (hint).
>
> I think the key is to have the second lookup (to find the component B
> that is contained in C) standardized via a interface.

Personally I think the exact opposite ;) 

I HATE the ComponentSelector interface and think it is a huge mistake to use 
it. If the ComponentSelector is simply access to a category of avalon 
components then I can't see why you can't depend on/lookup a component 
directly. 

ie Consider case where you look up selector with SocketManager.ROLE then look 
up SocketFactory component using "ssl" hint. Why could you not instead lookup 
the ssl factory directly via SocketFactory.ROLE + "/ssl". 

Much easier to do dependency checking, much easier for component implementer 
and gives the assembler much more choice in assembling the system.

-- 
Cheers,

Peter Donald
*------------------------------------------------*
| The student who is never required to do what   |
|  he cannot do never does what he can do.       |
|                       - John Stuart Mill       |
*------------------------------------------------*


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: ContainerManager and Sub-containers

Posted by Leo Sutic <le...@inspireinfrastructure.com>.
> From: Peter Donald [mailto:peter@apache.org] 
> 
> On Wed, 29 May 2002 21:09, Leo Sutic wrote:
> > > From: Peter Donald [mailto:peter@apache.org]
> > >
> > > Looks very similar to phoenixs layout with a few name changes ;)
> >
> > Very - and since you've been at it a while longer than I: Do you 
> > handle component/hint mappings, or just role mappings? That 
> is, can I 
> > specify that for Role X, selected with Hint Y, A should get 
> U, and B 
> > should get V? Or do you just allow the remapping to work on roles?
> 
> Phoenix just does Role mappings at this stage though just 
> recently something 
> similar to hints has come up. Basically any time there is a 
> Component A that 
> depends on a component B where B is contained within C. 
> 
> Examples include;
> 
> Depending on specific ThreadPool inside ThreadManager, 
> SocketFactory inside 
> SocketManager

Hmm. Just guessing, but a role -> role + hint mapping could do it.
Let SocketFactory implement ComponentSelector and lookup
SocketFactory.ROLE.
This gets mapped to a lookup (SocketManager.ROLE) and a select (hint).

I think the key is to have the second lookup (to find the component B
that is contained in C) standardized via a interface.

/LS 



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>