avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Leo Sutic <leo.su...@inspireinfrastructure.com>
Subject [SUMMARY] Context Concensus
Date Mon, 09 Dec 2002 22:50:36 GMT
All,

I believe we had a very productive discussion on the definition of a 
Context. Berin was right, though, in putting a hold on the discussions. It 
was about time we got that resolution out the door, given all the work that 
had gone into it.

OK, now back to Contexts... since the vote regarding the PMC voting 
procedure is in full swing, I want to use the pause in Context discussion 
for a short recap and reflection.

                               -oOo-

I'd like to summarize shortly the views and proposals that have been put 
forth, trying to note any equivalence between the proposals and point out 
where they differ, as well as trying to sort the proposals/views under 
Avalon4 or Avalon5. For example, Stephen's Locators and Noel's 
really-big-namespace are interesting ideas, but definitely something for 
A5. I don't want the ideas to be thrown out but on the other hand it must 
be understood that these things more deal with a new and better Context, 
instead of the Context as it is currently being used.

Finally, before I start, I like anyone who feels that their views are being 
misrepresented here to post a correction. I think there is much more common 
ground here than what is generally known.

                               -oOo-

                              AVALON 4

DATA

There appear to be consensus on the Context being a read-only map of values 
with defined types. For example, there is concensus that a component should 
be able to request that they key "avalon:work" maps to a File specifying 
the work directory.

As for accessing those values, there are two approaches:

  1) File workDir = (File) context.get( "avalon:work" );
  2) File workDir = ((WorkDirectoryContext) context).getWorkDirectory();

There appear to be concensus that (1) is, if not preferred, then at least 
acceptable by everyone. I know of none who actively opposes such usage.

The context requirements are specified on a type level. That, each 
component class would have an associated descriptor with what context keys 
are expected, what value type it expects, etc. The above would be specified as:

     <entry key="avalon:work" type="java.io.File"/>

optionally, with name remapping:

     <entry key="workdir" intent="avalon:work" type="java.io.File"/>

The actual DTD for this, as well as the way of creating and storing such 
data varies (XDoclet generated XML, attributes embedded in the .class file, 
etc.). However, there is concensus that the data itself should be 
represented in *some* form. All proposals seem to have a similar set of 
data elements: A key, a canonical key (avalon:work), and a type specifier.


OPERATIONS

There is not concensus on whether the Context should have any active 
operations. Stephen and Berin, for example, advocates that any active 
operations should be exposed via the ServiceManager, and that the Context 
should only be used to fetch data. (Note: By active operations, I mean for 
example requestShutdown().)

Others point to the Phoenix BlockContext interface.

However, there is concensus that a component should be able to specify any 
interface that it should be able to cast the context to. That is, for every 
interface T,

     public void contextualize (Context context) {
         T myContext = (T) context;
     }

the component should be able to declare that it expects to cast the context 
to a T. (For a less abstract example, replace T with BlockContext.)

This implies that the context must have all methods present in the T interface.

There is concensus that a method of specifying a context interface is 
needed in order to specify the Phoenix BlockContext (whether it is 
architecturally correct is another thing, and there's not concensus here). 
(This is also not the only conceivable way of specifying what methods is 
expected in the context, but this appear to be the one that there is some 
concensus at least as to it being a sensible way of doing it.)


PORTABILITY

Regarding portability there is concensus that:

  + For data, there should be a canonical set of context keys supported by 
all containers (possibly different depending on Avalon ME, SE, EE profiles).

  + For data, there is also consensus that the more entries a component 
requires, the less likely it is to be portable, and that this is 
acceptable. That is, it is OK for a Avalon EE container to supply more keys 
that an Avalon ME container. The tradeoff is: More requirements -> less 
portability, and it is concensus that this is acceptable, given clear 
guidelines on supported keys in different containers.

  + For operations, there is concensus that operations *may* be provided 
via the context. There is also concensus that this is a much more limiting 
requirement, but given the usual tradeoffs and the presence of clear 
guidelines, it is expected to be manageable, although not recommended for 
portability reasons.

                               -oOo-

                              AVALON 5

What follows is a *very* brief overview of the ideas that have been shown 
on the list.

LOCATORS

These unify all lookup operations. Much as a component can specify what 
services it depends on, it can specify what locators it requires. For 
example, a ServiceLocator or a SystemLocator. The locator is passed in in 
the contextualize() and service() methods, and the component can then cast 
the locator to any of the required interfaces before performing the lookup 
operations.

     void contextualize (Locator locator) {
         // Look up services...
         ServiceLocator sl = (ServiceLocator) locator;

         MyService ms = sl.lookup ("myservice");
         ...

         // Look up context info...
         SystemLocator sysLocator = (SystemLocator) locator;

         File workDir = sysLocator.locate ("avalon:work");
         ...
     }

The only difference between contextualize() and service() would then be the 
ordering in the lifecycle, as this would enable one to lookup services and 
context (what used to be) values at both points.


BIG NAMESPACE

Another way - that also unifies all lookup services - is to have a big 
namespace and a Locator interface:

     interface Locator {
         public Object lookup (String key);
     }

where key can be (for example):

     service:myservice
     context:workDir
     jndi:java:/something
     urn:something:else

The namespace (service, context, jndi and urn in the example above) would 
then be connected to a pluggable namespace handler in the container.


STAGED CONTEXTS

This idea has a different context depending on the lifecycle stage:

     public void init (InitContext initContext) { ... };

     public void start (StartupContext startupContext) { ... };

     public void stop (StopContext stopContext) { ... };

     public void dispose (DisposeContext disposeContext) { ... };

(
   The obvious (to me at least) parallell is:

     InitContext -> Context
     StartupContext -> ServiceManager
)

/LS


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