avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Berin Loritsch <blorit...@apache.org>
Subject Component Lookup Strategies and Tradeoffs (was Map and Array...)
Date Tue, 01 Oct 2002 14:54:22 GMT
Currently we have several ways of looking up components and resolving
them.  We typically refer to them by the container that implements them,
i.e. the ECM/Fortress way or the Phoenix/Merlin way.  Each has their
advantages and disadvantages.  Hopefully we can look at them and come
up with the best solution.

Issue #1: Component Lookup/Release
----------------------------------

Part of what the ComponentSelector solved was the need for lookup and
release mechanisms.  Simple types cannot provide release mechanisms,
so only ThreadSafe components can be safely used with simple types.
In the Phoenix realm, that is not a real problem as most services are
ThreadSafe anyway.  However, at lower levels (i.e. Avalon embedded
in another container hierarchy like Servlets) developing all components
as ThreadSafe is not always practical.  We need transient components.

Since the solution we come up with must work in the general case, the
compromise was the ComponentSelector--something that Peter D. regrets
to this day ;p.  In the embedded Avalon world (ECM and friends), the
ComponentSelector works very well because we can look up the components
we need from the selector by names supplied in the configuration.
It is a desparate need.

We have recently decided that we want to move away from a Selector
based approach--which would bring us back to Peter D.'s original
solution which is the hierarchical ComponentManager.  We still want
to explore that approach, because it gets rid of the intermediate
need of an additional lookup device (which includes Map/Array/
**Selector).

In order to fully get away from the need of the *Selector interface,
we need a way to mask the component management for transient components.
One way is through dynamic proxies that will pull an instance from
a pool as needed, and will automatically return it after a specified
period of inactivity.  The major issue is managing state information.
In order to work with transient/stateful components we need a session
mechanism so that a component can store its state in the session so
the client will never be the wiser.

BTW, for the benefit of all who weren't around the last time we had
the many components for one role discussion, a Releasable interface
was vetoed.  I proposed adding a method like "release()" to the
component interface that would provide real semantics for having a
Component interface as well as not requiring release() on the
CM/CS interfaces.  I think I was the only one in favor of that at
the time.


Issue #2:  Component Definition
-------------------------------

In the ECM/Fortress world, things are simple.  There is no meta info
(for the time being) to write, no assembly files to write.  That is
because they take advantage of the interface names as a lookup key
resolution policy.  They dynamically determine how to respond to a
lookup request.  In the Phoenix/Merlin world, things are more complex,
more powerful, and more static.  As a result, ECM/Fortress can easily
handle looking up components from a **Selector because the lookup
keys are typically part of the configuration.  That is a good thing
IMO.  The power of meta information comes at a price.

Until support was added for the array/hash return types (substitutes
for the **Selector), there was no real way to look at a collection
of components and determine at assembly/deployment time which components
you really wanted.  The problem is that the array/hash return types
really only work in the Phoenix arena because all the components are
ThreadSafe--not transient.  That said, I think the declaration of
array/hash/selector in meta information can be better stated.  At
development time, we know how we want to lookup information, we just
need to know the lookup value at runtime.  To support this, I propose
the following changes to the declaration and lookup of components:

<dependencies>
   <dependency>
     <service name="org.apache.MyService" as="#"/>
   </dependency>
</dependency>

With this change, we declare that we want the lookup for the specified
service to be a Map.  In fact we can do better by using words:
"array", "map", "selector".  The container knows how to bind the
required services from that point.  In our code, we have this:

void service( ServiceManager sm )
{
     Map services = (Map) sm.lookup( Service.ROLE );
     // use them here.
}

At assembly time, we specify them like this:

<block class="org.apache.MyComponent" name="myComp">
   <provide name="service1" role="org.apache.MyService"/>
   <provide name="service2" role="org.apache.MyService"/>
   <provide name="service3"
            role="org.apache.MyService"
            alias="myAlias"/>
</block>

There is no need to repeat the as="#"/as="map" in the assembly, because
we already know that the component is looking for multiple entries like
that.  This way we can leverage the power of meta-info with the
flexibility that was desired.  I would even go farther and say that we
would be able to remove the necesity for the role="..." attribute in the
assembly if the component only implements one role.


-- 

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


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


Mime
View raw message