avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stephen McConnell <mcconn...@apache.org>
Subject Re: reduction ad unum
Date Sun, 24 Nov 2002 17:43:05 GMT

Nicola Ken Barozzi wrote:

> Stephen McConnell wrote:
>> Nicola Ken Barozzi wrote:
>>> Leo Sutic wrote:
>>>> Stephen,
>>>> your point is taken that all operations that are not a lookup of a
>>>> constant value based on a key (such as getHomeDirectory)
>>>> can be seen as a peer service.
>>>> First, everything can be seen as a peer service. We don't really
>>>> need the Configurable interface. Instead, one could lookup a
>>>> configurator service:
>>>>     interface Configurator {
>>>>         Configuration getConfiguration ();
>>>>     }
>>>> and use the returned Configuration. The container would ensure you
>>>> got the correct config.
>>>> However, while it reduces the set of classes one has to deal with
>>>> ("everything is a service") there are practical issues with this.
>>>> Peter D. mentioned a few of them here:
>>>> http://marc.theaimsgroup.com/?l=avalon-dev&m=103809692826408&w=2
>>>> and I believe he's right.
>>>> My analysis would be that the real problem *is* the Context interface.
>>>> Specifically, that it is a total mess. What is it for? Constant 
>>>> value lookup?
>>>> Container specific services only? Container provided services in 
>>>> general?
>>>> If anything, this is something that has to be solved before we go on.
>>> Yes, I feel the same way.
>>> The Context is something that has been used in the past and is used 
>>> now  in many ways, like a sort of catchall thing.
>>> "Hey, where do we put this? Use the Context".
>> Q: I have a logger - how do I assign it to the object?
>> A: You use LogEnabled
>> Q: I have this static configuration fragment - how do I get this to 
>> the object?
>> A: You use Configurable
>> Q: I have a set of static parameters - how do I pass them to the object?
>> A: You use Parameterizable
>> Q: I have a logger - how do I assign it to the object?
>> A: You use LogEnabled
>> Q: I have a service - how do I suply this to the object?
>> A (a) In ECM/Fortress you lookup the service by passing in the 
>> service interface name
>> A:(b) In Merlin/Phoenix you declare a named dependency with you 
>> component and ask for it using lookup
>> Q: I have some data that I want to supply to my object - how do I do 
>> that
>> A (a) You use the Context interface
>> A (b) In your using Fortress or Merlin you can also apply the data to 
>> the component using an lifecycle extension
> If this is the case, I just make a ContextService, that gives me the 
> objects I want. Your explanation fails to make me understand the 
> difference between a Service and a Context.

In theory a Context could be expressed as a service.
But that doesn't help much.

I think it is much better to look at the implications from the point of 
view of a container concerning supply of a service, as opposed to the 
implications of suplying a context object.

Service provision
A ServiceManager/ComponentManager interface provides access to services. 
 The objects returned from a service or component manager are services 
derived from components.  When you invoke lookup, your potentially 
invoking the establishment of a new instance of a provider component in 
accordance with a lifestyle policy, processing of the provider component 
though the startup lifecycle, assignment of logging channels, population 
of the provider component with a confiugration and/or parameters, 
resolving depedencies that the provider component may have, providing 
the componet provider with its runtime context, possible application of 
extended lifecycle extension stages,including the deployment of the 
handlers for those stages, initalization of the provider, possible 
startup of the provider, possible proxying of the service interface, and 
returning the service interface to the invoking client.

Context provision
The context object is created by putting existing objects into a map 
under unique keys.  There is NO processing or interpritation of the data 
that is added to the context instance (aside from type checking).

There's the difference!

>>> I even wonder why we have a Context interface at all, since we are 
>>> casting as we do with Services (and there we have removed the 
>>> Component Interface). Context is for many a happy ComponentManager. 
>> Thats a very ECM mindset - ECM notion of service is not based on 
>> depedencies or the fact that a component explicity declares the 
>> servicees it provides.  In ECM you have a lookup mechaism and some 
>> mcahanics that handle things based on marker interfaces.  If you want 
>> to incorporate static service management into ECM you would discover 
>> that there are differences between a service and java,.lang.Object - 
>> most notable is a version, supplimenting this are attributes.  
>> Service != Object.
> I don't mean that "Context is for many a happy ComponentManager" is a 
> good thing. It makes us use as Services things that in fact are 
> Objects, without any proper decalarations and dependency resolution.
>>> Now, in real life, what is a Context for?
>>> Let me try to make a simple example.
>>> Let's say that I make my famous GooServer using Avalon. It's an HTTP 
>>> server, and it sends every single request to a chain of Goolets, 
>>> that are Avalon Components. The Server itself is a simple GooContainer.
>>>                ,------------GooContainer---------------------.
>>>               |                                              |
>>>               |                               |              |
>>>               |      /-----GooLet1-------\    | ----------   |
>>>   GooRequest  |     |                     |   |-|        |   |
>>>     ------->------------ goo(GooRequest)  |   | | Storage|   |
>>>               |     |                     |---| | Service|   |
>>>               |   ------ GooResponse      |   | |        |   |
>>>               |   | |                     |   | ----------   |
>>>               |   |  \-------------------/    |              |
>>>               |   |                           | ----------   |
>>>               |   V                           |-|        |   |
>>>               |   |                           | | Search |   |
>>>               |   |  /-----GooLet2-------\    | | Service|   |
>>>               |   | |                     |   | |        |   |
>>>               |   ------ goo(GooRequest)  |   | ----------   |
>>>   GooResponse |     |                     |---|              |
>>>     -------<------------ GooResponse      |   | ----------   |
>>>               |     |                     |   |-|        |   |
>>>               |      \-------------------/    | |Template|   |
>>>               |                               | |Service |   |
>>>               |                               | |        |   |
>>>               |                               | ----------   |
>>>               |                                              |
>>>               ,----------------------------------------------.
>>> When a GooRequest arives, the simple GooContainer intantiates the 
>>> Goolets that its Configuration specify, runs through the initial 
>>> lifecycle Interfaces (giving them also itself as a reference), and 
>>> calls the
>>>    GooResponse goo(GooRequest)
>>> on them one after the other.
>>> Each GooLet can be Composable, thus have a reference to Services 
>>> that are provided. As you see, there is no Context (yet).
>>> Imagine though that you have 3, 4, 5 requests, and concurrent 
>>> requests. Each Service is the same object as before, thus *is not 
>>> scoped per chain invocation*.
>>> Now the GooLet2 wants to tell Goolet1 something. It can only via the 
>>> GooResponse-GooRequest, because it's the only object in the above 
>>> scenario that is per-request.
>>> Hmmm, no Context yet...
>>> NOw I want to track sessions between invocations.
>>> Services are always the same.
>>> Requests are atomic... I need a Context. Something that gives me 
>>> information sharing per session. 
>> Ummm, something like a request context ?
>>> Now, what is a Context?
>>> If it's a bag to put values common to all Goolets, it's a Service.
>>> If it's to be shared by all Goolets in the same invocation it's a 
>>> Request.
>>> So it seems to be a bag to hold info between invocations but 
>>> pertaining to a certain criteria (session for example).
>> You describing the notion of a *request* context as opposed to 
>> something like a * GooLet* context.
>> In both cases the the context object is an instrument that can be 
>> populated with data and safely supplied to a consumer.
>>> So
>>>   X requests for X invocations
>>>   N services for X invocations
>>>   Y contexts for X invocations
>>> Where
>>>   Y<=X
>>>   N not related to X || Y
>>> This is not how Context is used now in most cases. It's used to get 
>>> a directory for example, which in this case seems to be a Service... 
>>> so?
>> I would disagree with the conclusion about most cases.  Given the 
>> framework contracts, there are many occasions where you want to pass 
>> a set of runtime parameters to an object, for example, I may want to 
>> pass a classloader, a date, and a public key chain. The configuration 
>> interface is clearly inappropriate as is the parameters interface, 
>> service interface is inappropriate these objects do not publish 
>> service interfaces - they are what they are - data that collectively 
>> define a context.
> >
>> A context instance is a readonly bag of tagged data. 
> Please expand on this. Especially on the "publis service interfaces" 
> part and the "readonly bag of tagged data".
> I have the strange feeling that the Context described here is a 
> ContainerRuntimeDataService. 

Answer to the first question:
If you follow the approach of static assembly, a container looks at a 
component and reads information in about the services it can provide. In 
a meta-driven work this information can include the service version, the 
classname of the service interface, and an arbitary set of attributes. 
 Using this information a container can establish an internal table 
which basically states that component X is a potential provider of 
service Y.  When a lookup on a service manager occurs, the implemetation 
of a service manager asks the container for the component that provides 
the requested service.  The container looks up the component provider 
based on the service that the component said it can provide.  

This is similar to ECM except that ECM resolves this information based 
on info in a roles file (loosely equivalent to meta) and does it at 
runtime whereas the formal meta-model approach enables this process to 
be done either at runtime or prior to runtime during a asembly phase.

Answer to the second question
The Context interface is basically a similar java.util.Map interface. 
 It allows readonly access to objects held in a table based on keys. The 
only behaviour it implies to get( key ).  The default implementation of 
context allows the creation of a context chain so that a context 
instance can have a parent, and unresolved requests to get( key ) go up 
the chain until they are resolve or there is no further parent and 
ContextException is thrown.  From the clients point of view a supplied 
context object is simply a collection of data keyed by names - each key 
is the tag the client uses to retrieve a particular data member - hense 
my expression "A context instance is a readonly bag of tagged data.".

Cheers, Steve.

>> Data can can be transformed into objects capable of providing 
>> behaviour by narrowing the data to some behavioural interface (such 
>> as a key-chain).  In such a case you are no longer dealing with the 
>> context object, your dealing with a functional object - i.e. its a 
>> seperate concern.
>> This is true in the scenario you describing above, its true in terms 
>> of the usage I apply context to, and its is totally consitent with 
>> the framework defintion.
>> So, where does this take us?
>> Cheer, Steve.


Stephen J. McConnell

digital products for a global economy

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