cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Vadim Gritsenko" <vadim.gritse...@verizon.net>
Subject RE: [RT] Resource Garbage Collection
Date Tue, 30 Oct 2001 13:27:05 GMT
> -----Original Message-----
> From: Carsten Ziegeler [mailto:cziegeler@s-und-n.de]
> Sent: Tuesday, October 30, 2001 2:13 AM
> To: cocoon-dev@xml.apache.org
> Subject: RE: [RT] Resource Garbage Collection
> 
> > Vadim Gritsenko wrote:
> >
> > Carsten,
> >
> > Could the behavior of RequestModelComponent achieved by using object
> > model:
> >
> > 	if(environment.getObjectModel().get("statistics")==null)
> > 		environment.getObjectModel().put("statistics", new X())
> >
> > I used (something like) this when implemented profiler...
> >
> Hi Vadim,
> 
> no not exactly. If your component needs some initialization you have
> everywhere you need such a component the following lines:
>   if (objectModel contains not object) {
>       create object
>       init   object
>       put    object in objectModel
>   }
> 
> And the other problem is that you have to release these objects
sometime
> again. So any mechanism must be provided which looks for all these
> objects after the request is finished and releases them.

I see. For profiler, I managed to do without RequestModelComponent, but
this concept is more powerful and is very useful for many other
applications. If vote is needed, here is mine +5.

Vadim

> 
> Carsten
> 
> > PS Not that I do not agree with this proposal, I do see necessity
for
> > this interface.
> >
> > Vadim
> >
> > > -----Original Message-----
> > > From: Carsten Ziegeler [mailto:cziegeler@s-und-n.de]
> > > Sent: Monday, October 29, 2001 10:02 AM
> > > To: cocoon-dev@xml.apache.org
> > > Subject: RE: [RT] Resource Garbage Collection
> > >
> > > Yes,
> > >
> > > garbage collection of resources seems to be a must-have.
> > > Four weeks ago we discussed with Stefano a similar approach
> > > which would fit in my eyes directly into this concept
> > > (See http://marc.theaimsgroup.com/?t=100197769000007&w=2&r=1
> > > for the full thread).
> > >
> > > The concept summarized: A new marker interface named
> > RequestModelComponent
> > > (with regards to the SitemapModelComponent, although the name is
not
> > > the point here) which marks an Avalon Component.
> > >
> > >   public interface RequestModelComponent extends Component {
> > >      void setup(SourceResolver resolver, Map objectModel) throws
> > >      ProcessingException;
> > >   }
> > >
> > > The behaviour for this would be:
> > > - The first time during a request processing a component marked
with
> > >   this interface is looked up, a new instance is created (or got
from
> > >   the pool) and the setup method is called. This object is stored
> > >   somewhere so that the ComponentManager has access to it for
later
> > >   requests.
> > > - The second, third.. time during the same request this component
is
> > >   looked up, it is get from the store and the setup() method is
> > >   not looked up
> > > - Every time a release is called on this object, nothing really
> > happens
> > > - When the request processing is finished, the ComponentManager
> > >   must really release all stored objects.
> > >
> > > So actually objects marked in this way are more or less ThreadSafe
> > > but per request exists a different instance.
> > > Although this is not a "real world example" and might not be
> > appropriate
> > > modelled, lets imagine a component for statistics. In order to
work
> > > correctly
> > > this component needs access to the objectModel (to get the request
> > object
> > > and
> > > from that the current requestURI) and it "logs" how many
components
> > are used
> > > during the processing of one request.
> > > Imagine a simple pipeline with a generator, transformer and
> > serializer.
> > > The generator looksup the "Statistics" component called SCA, it is
> > created
> > > from scratch (or taken from a pool) and the setup() method is
called.
> > > The generator now sends his information to SCA. Now the
transformer
> > > looks up a "Statistics" component to send his information. If now
a
> > new
> > > instance SCB would be created, this instance would not know about
the
> > > information
> > > previously send to SCA, so we need the same instance SCA here.
> > > As this instance is already setup there is no need to call this
method
> > > again.
> > >
> > > If in the same time a different request is processed parallel
which
> > uses
> > > the same pipeline (or any other, it doesn't really matter), the
> > generator
> > > looks up its own "Statistics" component, which of course can not
be
> > SCA as
> > > it is used in the other pipeline.
> > > It is a "new" instance which is used exclusivly in this pipeline.
> > >
> > > So summarizing it:
> > > - a ThreadSafe component is shared by all components  in all
requests.
> > > - a "normal" component is not shared at all, each component gets
its
> > own
> > >  instance.
> > > - a RequestModelComponent is shared by all components in the
*same*
> > request.
> > >
> > > Now, implementing this results in a similar behaviour as your
> > proposal.
> > > All RequestModelComponents are "collected" during a request by the
> > > ComponentManager
> > > and release (= garbage collected) at the end of the request.
> > >
> > > Carsten
> > >
> > >
> > > Berin Loritsch wrote:
> > > >
> > > > Developing with Cocoon is a fun and rewarding experience,
> > > > especially because it is hard write non-scalable webapps
> > > > on the platform.  Alot of this has to do with the limitations
> > > > on the developer, and forcing them to Do the Right Thing(TM).
> > > > Most of the enhancments have come out of a real need.  I
> > > > believe we have one more.
> > > >
> > > > The action we have has an interface that is simple, for a
> > > > reason.  We want to be able to encourage ThreadSafe programming.
> > > > I don't ever want to lose that.  However, we have to come
> > > > to grips with the fact that not everything follows this
> > > > ideal world.
> > > >
> > > > One example was that someone wanted to use an Action to obtain
> > > > a resource from a database (XML:DB to be exact), but needed
> > > > a way to release the resources at the end of the pipeline.
> > > > I think this is a reasonable request, but it does raise some
> > > > questions.
> > > >
> > > > * Which pipeline?  One master pipeline that makes use of
> > > >   aggregation or the "cocoon://" protocol is made up of
> > > >   several shorter pipelines spliced together.
> > > >
> > > > * How do we handle action sets?
> > > >
> > > > * Should things like this be handled by a different mechanism?
> > > >
> > > > So, how do we come up with a model that works?  The basic
> > > > problem restated is that we need a way of holding on to
> > > > resources for the length of the request.  After the request is
> > > > over, the resource is released.  Logically, this makes sense,
> > > > but putting something like this together is difficult in
practice.
> > > >
> > > > The issue actually stems from our greatest asset: components.
> > > > The very Component Based Design that Cocoon is built with
affects
> > > > how things work together.  The easiest design to implement is
> > > > one that acts on immediate need.  As an analogy, I will use
> > > > memory management.
> > > >
> > > > In assembly and machine language, the programmer is required to
> > > > manually set up the work areas, and perform all work within
those
> > > > areas.  This is equivalent to Pre-Cocoon days where your logic,
> > > > content, and display information were all mixed together in one
> > > > resource.  It is the way you work with JSP, ASP, and ColdFusion.
> > > > We all know this is bad, and don't want to go back to those
> > > > awful working conditions if we can help it.
> > > >
> > > > With the advent of higher level languages like C and C++, we
> > > > were given the blessing and curse of heap managed memory
allocation.
> > > > It was great because now we didn't need to set asside work areas
> > > > ahead of time.  Sure there was a performance penalty for
allowing
> > > > the OS to set up your memmory allocation and management, but it
> > > > was worth it.  If you were careful, you would allocate and
> > deallocate
> > > > your memmory as you needed to.  The problem came when you had
> > > > to have some allocated memmory persist between scopes.  It is
> > > > easy to remember to deallocate memmory when you use it all in
the
> > > > same method.  But what if you needed to hand that memmory
reference
> > > > to another method--one that you may not have written?  If the
> > > > memmory was deallocated by that method your were SOL (S**t Out
of
> > > > Luck--a military acronym).  This is where Cocoon is now.  If
> > > > a Component is asked for (looked up), you have to be careful to
> > > > release it--otherwise it *may* cause resource leaks.
> > > >
> > > > Then cam Java and a slew of other languages that favor garbage
> > > > collection to explicit deallocation.  You have no direct control
> > > > over when a memmory area is going to be reclaimed, but you do
know
> > > > it won't happen while you are still referencing it.  That means
> > > > you can pass the memmory reference around your program without
> > > > fear of it being deallocated.  This is where Cocoon needs to go.
> > > > In other words, Cocoon needs a mechanism to 1 have a reference
> > > > to a resource (Component or Object) last for an entire request.
> > > > At the end of the request, the resources are cleaned up.
> > > >
> > > > So how do we design something like this without screwing our
heads?
> > > > The first is to narrowly define the scope and access of these
> > > > objects.  The second is to mark these objects with an interface
> > > > so they can be handled properly.  This does require some
repurposing
> > > > of the RequestContext I proposed recently.  While many people
are
> > > > against using the RequestContext as a "communications" area, it
is
> > > > perfectly suitable for passing object references for the life of
> > > > one request.
> > > >
> > > > In order for the RequestContext to behave properly, and enforce
the
> > > > contracts of mapping resouces to specific names, the put()
method
> > > > must be write-once.  That means you can never overwrite a
resource.
> > > > It also means that the developer needs to be smart about the
> > resource
> > > > names he uses.  We should not impose a strict naming scheme, but
> > offer
> > > > one that should be scalable--especially considering the Cocoon
> > WebApp
> > > > proposal by Stefano.
> > > >
> > > > One proposed naming scheme would be much like URLs:
> > > >
> > > > http://infoplanning.com/schematic-access/user
> > > >
> > > > Another would be a simpler form of the above version:
> > > >
> > > > infoplanning.com:schematic-access/user
> > > >
> > > > Still another solution would be equivalent to the
> > > > java pakage/classname solution:
> > > >
> > > > com.infoplanning.schematic-access.user
> > > >
> > > > Using replacement variables, the resources would be named with
> > > > these variables:
> > > >
> > > > ${company.domain}:${project.name}/${object.name}
> > > >
> > > > This ensures that the probability of you having a unique name
> > > > within a system is high.  The developer may find that adding
> > > > one more level to the heirarchy might make sense (i.e. a
> > > > ${module.name}), but it isn't necessary for most projects.
> > > >
> > > > Next, we need to specify where the resource collection happens.
> > > > In order to maintain the simplest and most portable solution,
> > > > I would propose the RequestContext be managed by the Cocoon
object.
> > > > That way, it is handled the same no matter what the environment
> > > > is.
> > > >
> > > > Lastly, we need to provide a marker interface for resources that
> > > > must be properly released when the request is over.  Objects
like
> > > > Strings, and non-pooled objects can simply have their references
> > > > nullified.  Other objects like the resources mentioned above
> > > > need a Reclaimable interface with a single method, reclaim().
> > > > For instance:
> > > >
> > > > public interface Reclaimable {
> > > >     void reclaim();
> > > > }
> > > >
> > > > The Reclaimable interface tells the resource to clean up after
> > itself.
> > > > It is up to the implementor of the Reclaimable interface to
decide
> > on
> > > > the exact mechanism.  The usual method would be to store a
reference
> > > > to it's pool or component manager and call put() or release() on
it.
> > > > This way, Cocoon is not altered too much architecturally, and
the
> > > > ComponentManager/Selectors are not altered from their purpose.
> > Finally,
> > > > it also means that encouraging the use of RequestContext for
these
> > types
> > > > of things encourages a consistent design and method of cleanup.
> > > >
> > > >
> >
---------------------------------------------------------------------
> > > > To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
> > > > For additional commands, email: cocoon-dev-help@xml.apache.org
> > > >
> > >
> > >
> > >
---------------------------------------------------------------------
> > > To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
> > > For additional commands, email: cocoon-dev-help@xml.apache.org
> >
> >
> >
> >
---------------------------------------------------------------------
> > To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
> > For additional commands, email: cocoon-dev-help@xml.apache.org
> >
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
> For additional commands, email: cocoon-dev-help@xml.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org


Mime
View raw message