Berin Loritsch wrote:
>>From: Stephen McConnell [mailto:[EMAIL PROTECTED]]
>>
>>Berin Loritsch wrote:
>>
>>
>>
>>>What we need to address is the use cases from several current use
>>>cases. We *have* to address what the best way to solve each use case:
>>>
>>>1) Simple CM lookup and use:
>>> This is probably the majority of cases (70%?). A
>>>
>>>
>>component looks up
>>
>>
>>> another component by interface.
>>>
>>>
>>>
>>I belive this use case is an abuse of the CM. The CM is a
>>utility supporting interaction between the container and the
>>component. In this context the inteface information is
>>redundant if the container provides support for metadata. If
>>not, the passing of string that is not opaque is a workaround
>>to support either a container or component deficiency. This
>>simple case can be easily support by seperating the usage of
>>a lookup interface for commonent aquistion as opposed to
>>component lifecycle servicing.
>>
>>
>
>
>Stephen, this is the core use case.
>
>lookup(MyComponent.ROLE);
>
>Nothing more. Read into what you want, but I am talking about
>how it is used NOW.
>
And my coment was focused on the core use case. The core use case is a
situation where there is information suplied by the client that is
interprised by the container. While that may represent the cure usage
pattern - it does not mean that it is a scalable rational path for
development. In fact, lets be blunt - it isn't. Remove interpritation
of the sting, give the namespace scope to the component - then we are
talking about something we can move forward with. Once this is
recognized - then we can focus on facilitating migration - tools, apis, etc.
>>> It doesn't care about implementation
>>> issues, but it must exist for the component implementation to work. The current
>(A4) CM interface accomplishes this without problem.
>>>
>>>2) Optional CM lookup and use:
>>> This is less common, but definitely appropriate. A component tests for the
>existence of an optional component--which it will use if it exists. If the component
>does not exist, it is not exceptional. This is in contrast with use case 1 where the
>missing component *is* exceptional. The current (A4) CM interface accomplishes this
>without problem because of the containsCOmpoennt() method.
>>>
>>>
>>>
>>This is another example of the usage of the CM outside of te scope of
>>component lifecycle management. The real issue here is
>>"should this be part of a CM supported behavior". If it should, then ...
>>
>> a) a component dependency declaration must declare what is
>> effectively a wildcard constraint
>> b) and this constraint could be rejected if it conflict with
>> container policy concerning diclosure of components
>>
>>
>
>??
>
>Sometimes I get the feeling you don't pay attention.
>
<sidenote>
I'm really trying. I don't use Cocoon - I don't use ECM - I do care
about Avalon development -and in particular the framework - that means I
do care about about the Cocoon community. If you have the impression
that I'm not paying attention - then jump in at the appropriate points
and explain what the issue is - what are facts that I'm missing - and as
just about everyione here knows I'm missing lots of information. What
I'm not ready to do is to sit by and watch a re-run of fundimental
mistakes in architecture. Getting this right is important - that means
really assessing the issues - exploring alternatives (even if painful) -
understanding the arguments for and against. Once you arrive at that
position you can figure out if migration is a rationale or not - but at
least you have isolated issues at the architectural level.
</sidenote>
>
>Ok, let me restate it. Let's say I have a component that
>generates information. It _requires_ a SourceResolver
>component. However, if the environment has a Cache component,
>it will use that.
>
>The Cache is not necessary for the generating component to
>opperate--it just allows it to resolve future requests
>quicker.
>
>Therefore, it will check to see if the cache component exists.
>If not, it will continue processing as normal--just without
>the benefit of a cache.
>
>The component will and should be able to function if it is
>used in an environment that does not supply a cache. Artificially
>making it a _requirement_ is a false contract.
>
>
All of this is about poicies that a container applies in the context of
constraints supplied by the client component. You described a scenario
in which a component has a *option* dependecy on a service. We can
ignire the selection relative to multiple providers - that another
topics - what should not be ignored is the responsibility of the
compoent to decare the depedency. Apply queries (via roles, hints, etc)
is the same as case 1 - ok so the client knows its optional - doesn't
change anything as far as a container is concerned. As long as
dependeciues are undeclared is a scenario that is outside of a foral
container/component contract. Try to think of it this way - any time a
client sends something to a container for interpritation (i.e. a
non-opaque string) - your bereaking the generic contract - you
eliminating portability of components - and you limiting applicability
of the container.
>>>4) Multiple resolutions of an implementation for the same role:
>>> The Container is responsible for this logic. Currently, Phoenix
>>> uses meta-information and a mapping file to manage the Component/
>>> role mapping.
>>>
>>>
>>>
>>Merlin also uses meta-information.
>>
>>
>
>I wasn't excluding it.
>
>
>
>
>>> However this can be difficult to understand.
>>>
>>>
>>>
>>Disagree on that. The meta declaration in a .xinfo file is drop dead
>>simple. Its also auto generatable using javadoc tags.
>>Currently Merlin
>>support the complete .xinfo used in Phoenix. Merlin also includes
>>additional information concerning implementation policy and release
>>configuration. This subject (or the convergence of that) are under
>>discussion. Done correctly, this means the ability to fully
>>package a
>>deploy at the component level - and transparent from component to
>>application via Phoenix.
>>
>>
>
>Take off your seasoned developer hat, and put on your newbie hat.
>(Easier said than done, I realize). I have explained it to several
>junior developers many times. Some of them are particularly dense.
>It takes a while for the light bulb to go off in their head.
>
>Now that we have taken the junior developer tack, now try explaining
>that to an administrator who wants to override the default mappings
>of component implementations to something different.
>
1. I'm not a develper.
2. I may be seasoned :-)
3. My own light switch isn't working all the time
*click* *click* *click* - zutt its gone again
4. *click* its working!
Meta is not something that is overriden (its part of the type).
Administator concers will be focussed on declaration of (a) assembly and
(b)
constraints on instances. Even ECM enables declaration of configuration
management. ECM's assembly ins't manageable (because it inside the
component
implementation - whereas the scenaio I'm talking about, all of this is
available for management. It not a code issue. Its not a developer issue
- is a solution much more geared towards management.
Take of the newbie hat and put on a suite!
>>> The maintainer of a project that someone inherits has a lot
>>> of homework before they can understand how to map roles and
>>> components when there are multiple instances and the returned
>>> value changes based on the context of the calling component.
>>>
>>>
>>>
>>The above does not compute.
>>What context are you referring to?
>>
>>
>
>
>Example:
>
>Cocoon. Several sitemaps forming a heirarchy. In each heirarchy the
>component bound to Generator.ROLE/stream might be replaced in a child
>sitemap. Or it can be done somewhere in the middle. I.e. defined in
>the root sitemap, overridden in a child sitemap, and used in a child of
>that sitemap. You have to know the context or scope of the the
>component
>resolution.
>
This is an excellent example of why the Componentmanager.lookup operation
is not the right tool for the job. The application context goes way beyond
the scope of a service/component manager/locator. You are describing much
righer infromation. To handle this you have to seperate yourself from the
framework by at least one step. Use the framework to locate the service
that is capable of supporting these demands.
>
>Also, as you have repeatedly demonstrated that while it is not necessary
>to bind the same role name for all components, it is definitely harder
>to follow when you are maintaining your components if one component
>calls
>the SSL ConnectionManager "ConnectionManager.ROLE/SSL" and another calls
>it "ssl-connection". Consistency is very important in maintenance.
>
Interestingly, in my non-standard approach to life, flying in the face of
established convention and wisdom, challenging the established practices
(which I can assure you I never every though I wouldever do) - it turns
out that my components are completly in control of thier own detiny - they
are self contained - they are not linked computationally to some interfacee
published somewhere with a public static member called ROLE. And what's
even more interesting is that this isn't a problem - becuase in reality
the information isn't needed. It only becomes an issue when your allowing
the container to interprit what you supply. Now you and I know that the
only justifiable excuse for this is that it makes my components consitent
with the other 70% - but so what - my components will not run in either ECM
or Fortress because neither have any notion of a type formally expressing
services or dependencies. So at the end of the day - the upside in
following
the convention amouts to the sum total of zero (well, lets say a sum total
of something rather small - it's actually not zero - but that's another
thread).
>
>
>>> We need a better way to explain this--because while it is
>>> powerful, it is too confusing for newbies.
>>>
>>>
>>>
>>When I first came across Avalon (the project) I spent a lot of time
>>trying to figure out what was available. I did a lot of digging into
>>ECM but found it to be way more complex than Phoenix (and
>>that included all of the pain related to Phoenix assembly stuff).
>>The core bits we are talking about for meta declaration are tiny -
>>simple - very simple - and easy to incorporate into a container. What
>>is really confusing for newbies is runable HelloWorld components (or
>>more specifically the absence of them). I've just finished puttting
>>in place some demos on the Merlin CVS that show simple and composite
>>services - for the developer it is a drop-dead-simple exercise
>>providing they have container solid support.
>>
>>
>
>That is something we need to take care of. However that is a
>documentation concern.
>
>
I think its much more than documentation. You can use decumentation as
a means to rationlize and justify stuff and to eduction, But if you
starting of with something that is clean complete model - the process
becomes much easier. Just think about things like RoleManager - Leo
mentioned that he does not understand it - I know that I don't
understand it (and still dont) - but the important thing is that I know
that I don't need to understand it because I know that in a complete
model it isn't needed. That means the complete model is simpler. That
measn its easier to manage - that means less documentation - that means
higher adoption levels - need I go on?
>
>
>
>
>>>5) Multiple resolutions during runtime for the same request:
>>> Nothing really handles this well. It is hacked together by the
>>> component selector/service selector in A4.
>>>
>>>
>>>
>>Which is basically a workaround pending finalization of a
>>metamodel. I have tools I'm using that give me the suite of
>>options available for given component dependency. From this
>>- you will be able to plug in a selection policy handler that
>>resolves options down to a single service to supply to the
>>component. This seperates the issue of custom policies
>>for an overall meta-management framework.
>>
>>
>>
>>> The problem is best
>>> illustrated by a transformer. A document or transaction can be
>>> processed by several different transformers at runtime before
>>> the request is committed. Two examples include the Cocoon use
>>> case, and my data transformation server. The data transformation
>>> server passes a transaction object which multiple transformers
>>> may be applied to it before it is serialized to the persistence
>>> layer. Cocoon does the same with SAX events. This is what the
>>> proposed lookup(role,hint) hopes to solve.
>>>
>>>
>>>
>>I think this is a seperate concern - it can be handled by a registry
>>interface that can expose lookup( role, hint, whatever)
>>semantics but is independent of a CM lookup.
>>
>>
>
>How do you really propose to choose the correct Transformer? The
>container (in this case) is also a component responsible for resolving
>a request. The rules for a particular component can require five or
>more different types of transformers.
>
The container supplier a service to the component.
The service is a ComponetRegistry that has operations that handle whatever
it is you need to handle this level of complexity. It's basicaly the
same as
what you do now - except that you need to shift this application logic
out of
the component manger astraction layer.
>
>
>The important thing is that the component/container needs to resolve
>the correct transformer for the particular stage in the pipeline.
>
>
And the solution is to shift as much of this into type meta information.
Anything else should be handled by a service, suplied by a component
manager, that handles service resolution for the client. The supplied
service may have a privaliged relationship with the container if you
wish - but the bottom line is that you move the problem from the
abstraction of generic container to component interaction to the
abstract space of the problem - i.e. service query management and
resolution.
>
>
>>>We need to account for every one of these use cases in a straight-
>>>forward way. The design constraints we should work within should
>>>be:
>>>
>>>* Do not force the client to do too much work. The client needs
>>> to be easy to implement. Otherwise A5 is not of any use.
>>>* We should make it conceptually easy--not conceptually hard.
>>> Avalon already suffers from the learning curve necessary between
>>> Component-Oriented Programming and Object Oriented Programming.
>>>* We need to make the containers easy to understand or they will
>>> be forced into obscurity because noone wants to have to debug
>>> a container just to get their component to work.
>>>
>>>I think this will provide the proper conceptual framework to design the nextgen
>ComponentLocator.
>>>
>>>
>>>
>>I think we need to take a good long look at usage versus
>>abusage. The CM/SM interfaces define a utility through which a container
>>can supply dependent services to a component during the lifecycle
>>processing phase. As soon as you apply supplimentary scope on CM/SM, the
>>probelm expands dramtically and we see the current level of consufion about how the
>>interface is used. Bottom line - this is easily correctable without modifying the
>CM/SM
>>lookup signature.
>>
>>
>
>Outline a proposal. Please, enlighten us.
>
>
I though I had already done that?
(see other messages in this and related threads).
Cheers, 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]>