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

OSM SARL
digital products for a global economy
mailto:[EMAIL PROTECTED]
http://www.osm.net




--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to