cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Leo Sutic" <leo.su...@inspireinfrastructure.com>
Subject RE: Fortress Migration Strategy
Date Thu, 16 Oct 2003 06:33:30 GMT
Stephen, Berin,

I think Cocoon uses a stack-based scheme that can be implemented by the
container,
although it can't be exposed to those that only see the
Component/ServiceManager
interface.

This is pretty much how it works:

 1. Define a method called beginProcessing in the container. This method
    creates a Collection of component instances and pushes it onto a
    Thread-Local stack. Note the thread-local thingy.

 2. Every call to lookup will look at the top of the stack, and if it
    finds a Collection there, add the instance it returns to that
    Collection.

 3. Every release will remove the component from any Collection in the
    stack. This is O(n) in the number of invocations of beginProcessing.

 4. Finally, define a method endProcessing that pops the top Collection
    from the stack, and releases all components in it.

 5. Code like this:
     beginProcessing (); // Checkpoint
     try {
         doStuff (request);
     } finally {
         endProcessing (); // Rollback to previous checkpoint, i.e. four
lines back
     }

What does this mean? Well, it means that when endProcessing is called,
any components
lookup'ed in the thread doing the doStuff() are released.

Think of it this way - we can consider everything to be single-threaded,
since we
only deal with thread local variables. When we enter doStuff we know
that no components
have been looked up. Then doStuff does stuff. Now, we have a record of
all components
that have been looked up but not released in the Collection where we put
them in step
(2) above. So endProcessing releases them.

I think this (a) how it works in Cocoon now, and a per-request
lifecycle/lifestyle.

/LS

> -----Original Message-----
> From: Stephen McConnell [mailto:mcconnell@apache.org] 
> Sent: den 16 oktober 2003 04:57
> To: dev@cocoon.apache.org
> Subject: Re: Fortress Migration Strategy
> 
> 
> 
> 
> Carsten Ziegeler wrote:
> 
> >Berin Loritsch wrote:
> >  
> >
> >>Carsten Ziegeler wrote:
> >>
> >>    
> >>
> >>>Berin Loritsch wrote:
> >>>
> >>>Yes, I think this is basically our extension together with the
> >>>      
> >>>
> >>ParentAware
> >>    
> >>
> >>>support.
> >>>
> >>>* ParentAware
> >>>  A selector (or any other component) can declare that it is
> >>>      
> >>>
> >>ParentAware,
> >>    
> >>
> >>>which
> >>>means if you have a hierarchy of component managers and a 
> component 
> >>>is looked up in a child CM it get's a reference to a 
> component looked 
> >>>up in
> >>>      
> >>>
> >>the parent
> >>    
> >>
> >>>CM.
> >>>This is useful for nested selector e.g.
> >>>      
> >>>
> >>Please elaborate a bit more.  First, what problem does ParentAware 
> >>solve, and why can't it be done with normal component resolution 
> >>semantics?
> >>    
> >>
> >
> >When you have a hierarchy of component managers (I still call them 
> >component managers :) ), and you lookup a selector on the 
> child CM and 
> >then try to lookup a component using a hint that is not 
> defined in this 
> >selector but in a selector with the same role defined at the 
> parent CM, 
> >then the selector of the child CM can forward the lookup to 
> the parent 
> >one. Actually this is used in Cocoon for all sitemap components resp.
> >for the selectors for these components. So a selector for a generator
> >in a sub sitemap gets via ParentAware a handler (locator) to get
> >the selector defined in the parent sitemap.
> >
> 
> All of the above is implementation specficic description.  As 
> far as the 
> client side of the equation is concerned - imagine you were 
> container-agnostic - is the client providing sufficient 
> information for 
> a solution?  Yes - or no, can you provide a summary of the client 
> (consumer component) infromation that is available and how this 
> information is supplied to the contaier under the current 
> implementation?
> 
> >
> >  
> >
> >>    
> >>
> >>>>I believe I can solve these in the following manner:
> >>>>
> >>>>Request Scoped Components:  Create a new lifestyle handler for 
> >>>>Fortress.
> >>>>        
> >>>>
> >>>Yes, should work, but we currently have this in two flavors: The 
> >>>RequestLifeCycleComponent and the GlobalRequestLifeCycleComponent. 
> >>>The GlobalRequestLifeCycleComponent is one instance per global 
> >>>request comming into Cocoon. Even if this request creates sub 
> >>>requests (using the cocoon protocol), it's still one instance.
> >>>The RequestLifeCycleComponent is oen instance per request. So, each
> >>>internal request gets its own set of RequestLifeCycleComponents.
> >>>Example:
> >>>a) main request looks up a component of role A
> >>>b) main request invokes sub request (cocoon protocol)
> >>>c) sub request looks up a component of role A
> >>>d) main request looks up a component of role A again
> >>>
> >>>I) The component is a GlobalRequestLifecycleComponent
> >>>a) main request gets instance ONE
> >>>c) sub request gets instance ONE
> >>>d) main request gets instance ONE
> >>>
> >>>II) The component is a RequestLifecycleCOmponent
> >>>a) main request gets instance ONE
> >>>c) sub request gets instance TWO
> >>>d) main request gets instance ONE
> >>>      
> >>>
> >>Help me to understand the need for the difference a bit 
> better. Am I 
> >>correct in thinking that this is largely a performance type of
> >>"enhancement", or was
> >>there a technical issue driving this solution?
> >>
> >>    
> >>
> >Yes, basically. The typical use case is that you have *data* the 
> >component works on that is tied to the current request (or 
> subrequest). 
> >So the usual way would be to use a poolable component and 
> tie the data 
> >to the request. But this is bad for performance, because if 
> e.g. this 
> >component is looked up at three different places, you get three
> >instances and each component has to do a lookup in the
> >request attributes to get the data.
> >  
> >
> 
> A.k.a identifiable lifestyle strategy.
> Can this be handled with a service .. e.g. getMySessionThing( 
> sessionID ) ?
> 
> >>I am happy to help make this a possibility, but in many
> >>ways what we have in the "CocoonComponentManager", the use of 
> >>statics is scary.  With those things you have to ensure proper 
> >>synchronization, which can in turn reduce the scalability of 
> >>Cocoon.
> >>    
> >>
> >Yes, agreed. I'm trying to get rid off these statics but 
> haven't found 
> >a way yet. If we somehow can manage this, I'm absolutely happy!
> >  
> >
> 
> Any reason wny this could not be moved to a service .. e.g.
> 
>     StatsMagic magic = (StatsMagic) lookup( "magic" );
>     Specail special = magic.doSomethignSpecal( stats );
> 
> I.e. the issue is a Coccon issue as opposed to an Avalon generic 
> container issue.
> 
> >  
> >
> >>It would be easy enough to support a Request lifestyle by 
> binding the 
> >>component to the HTTP request being serviced at the time.  That 
> >>solution would generally be a GlobalRequest lifestyle.
> >>    
> >>
> >Yes.
> >
> >  
> >
> >>The distinction between the two makes me think
> >>that the request lifestyle might be better served by other means.
> >>
> >>Fortress and Merlin both have a PerThread lifestyle, which can also 
> >>satisfy the global request.
> >>    
> >>
> >Ok.
> >
> >  
> >
> >>If each sub-request has its own "request context", then we 
> can convert 
> >>the Global Request to a PerThread type of component.
> >>    
> >>
> >Yes, each sub request has an own "request context", so yes 
> this could 
> >work.
> >
> >But what happens if I process one request with multiple threads?
> >
> 
> It breaks if you assume a per-thread lifestyle.
> What you describing is a per-key lifestyle. That needs a new 
> lifestyle 
> handler in Avalon.
> 
> >We have, e.g. content aggregation that can be processed to 
> some extend 
> >in parallel. Now, you want to have the same components for 
> both threads 
> >as this is the same request. Is this possible?
> >  
> >
> 
> No.  Unless you declare a componet that does this backed by 
> some classic 
> componets (i.e. you move it to an explicit service).
> 
> >  
> >
> >>However, things will break down when someone comes out with 
> a Servlet 
> >>container that can handle multiple requests in one thread, and the 
> >>component in question has a particular order imposed for 
> method calls 
> >>(i.e. SAX content handler style components).
> >>
> >>Help me to understand the issue so that my "quick and dirty" can be 
> >>turned into something that scales better.
> >>    
> >>
> >
> >Yes, that would be great - now, basically I really hope that we can 
> >loose all the static things and make a cleaner approach. But 
> currently 
> >I see no way for the request lifecycle component, but perhaps it is?
> >  
> >
> 
> What you describing is to me a "per-identity" lifestyle and 
> that means 
> either (a) a specailized lifestyle handler in Fortress and 
> Merlin or, a 
> gernic custom lifestyle object model.
> 
> >  
> >
> >>>>SourceResolver specifics:  I need some input on how 
> exactly you are 
> >>>>extending
> >>>>                           this.  I might be able to 
> handle it with an
> >>>>                           Accessor lifecycle extension.
> >>>>        
> >>>>
> >>>The SourceResolver component uses a base directory to resolve 
> >>>relative URIs. The SourceResolver in Cocoon always 
> resolves relative 
> >>>URIs to the current sitemap, so during the processing of a request 
> >>>this information changes. But the component itself is e.g. 
> looked up 
> >>>at the initialization phase of the action etc.
> >>>      
> >>>
> >>I see.  So if we have each mounted Sitemap/Block being 
> encapsulated in 
> >>a sub-container, we can have a new SourceResolver per 
> container....  
> >>Of course, the ServiceManager supplied to a component will 
> only be for 
> >>the container that
> >>set up the component.  That won't work reliably.
> >>    
> >>
> >
> >Hmmm, no it won't work. Here is one problem:
> >
> >Imagine a thread safe component that has a service method
> >that gets in a uri as a string and is used from various places.
> >Now this thread safe component looks up a source resolver
> >on initialization, but it should resolve the uri provided
> >from a client of this component look up relative to the
> >sitemap the client was looked up.
> >
> 
> To restate this is another terminology - the sitemap is 
> establishing a 
> runtime context and this context needs to be exposed to other 
> components 
> that we can consider as children (or scoped) components 
> relative to the 
> sitemap.  I.e. we have a container that has aquired a sitemap, the 
> container interprets the sitemap and sets up a number of subsidiary 
> components that will enable execution of the sitemap fragment, the 
> components will require some context data that is based 
> on(opr derived 
> from) the site map.  During runtime invocation the components 
> implementations will be adaptive to the supplied context arguments.
> 
> Question for Casten: does that sound rationale?
> Thought for Berin: this is all about the dynamic meta-model 
> composition 
> .....
> 
> Stephen.
> 
> >
> >Carsten
> >
> >
> >
> >  
> >
> 
> -- 
> 
> Stephen J. McConnell
> mailto:mcconnell@apache.org
> 
> 
> 
> 
> 


Mime
View raw message