cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Berin Loritsch" <>
Subject RE: [Design] ContainerManager is under fire--let's find the best resolution
Date Thu, 06 Jun 2002 16:34:06 GMT
> From: Leo Sutic [] 
> Berin,
> I am 75% for your new CM interface. The problem is point 4.

Am I not a prophet?

> Assume you have a CM that automatically reclaims all 
> components after each request. That is, for Cocoon, when the 
> request comes in, the CM starts keeping track of what 
> components have been taken out, and when the request has been 
> processed, they are release()'d (or equivalent method).
> Now introduce pooled components.
>     If more than pool-max components are looked-up during 
>     the request you are not performing well, as you empty
>     the pool.

I thought I already did introduce pooled components.  It's
really simple.  The GC process for components releases them--just
like we currently do.  The GC process is done after the Response is
committed.  The difference is in *who* releases the component.
The onus is on the container--which already automatically tracks
each component anyway.

What is happening is that we don't have to rely on the developer
to remember to release the component in the proper location.  That
ends the problems with memory leaks because some error condition
forces the function to exit before the component is released.

> What I need to be convinced that release() isn't needed is:
>  + a description of how does it work with pooled components

Did you not read the entire mail?

The GC routine for the container collects any components that need
to be reclaimed into the pool.  As a result we will have fewer
dangling components than is currently possible.  Right now, we have
the equivalent of C++ memory allocation.  The onus is on the developer
to get it right.  The GC brings the component into the Java age where
GC is the norm.  You don't have to worry about deleting everything
you new in Java, the user doesn't have to worry about releasing
everything you lookup.

>  + a guarantee that the client will *never* have to care about 
>    whether a component is pooled or not. And I do not mean
>    a mandatory 
>       if (component instanceof Poolable) 
>           manager.release (component);

It happens in the container.  The policy can be a timeout, or it
can be request based.  Whatever.  The container tracks what components
were looked up (as it can do), and when the GC policy indicates it
is time to collect instances--the container does the hard work.
It isn't as hard as it seems.

> > From: Berin Loritsch []
> > 
> > In order to make it easier for the component developers, we
> > need to have a dynamic proxy generator (that would also help 
> > with DataSourceComponet too...). It would wrap the interface 
> > to enable garbage collection of components. All a client is 
> > responsible for is to request the component.
> The problem with this being that you have to care about 
> whether a component is pooled or not to get maximum performance.

No, that is the container's responsibility.

> Assuming a component that is expensive to instantiate but 
> often used and that does not have an unambiguously defined 
> end-of-duty event like the SAXTransformer's endDocument you 
> are left with two choices:
>  1) Add a "return-to-pool" method that the client must call.

If your component interface has a method that is called when you
are done (ala JDBC Connection.close()) then that is one natural
clue to the container.  The GC mechanism is still the best.

>  2) Add a timeout, which must be set low for the instance to
>     have time to return to the container in time for the next use.
> In case 1, this method is equivalent to release(), and you have just 
> traded one mandatory method call for another. Case 2 is just 
> not very good - set the timeout too low and you will get 
> problems if the component is still used after it has timed out.

Like I said it does require a change in how you think about
components and their interfaces.  I am advocating a GC mechanism
which is orthagonal to either 1 or 2.  For Cocoon the GC policy
would be after the Response is committed.  For something else,
a timeout policy might be worthwhile.

For yet another solution, the Container can essentially combine
timeout and guranteeing a reference is good.


Proxy that releases the component instance after a timeout of
100 ms will wait as a container of nothing until it is either
GC'd by the JVM or until an interface method has been called.
In that case, the call blocks until a new Component instance
is pulled from the pool.  The method is then called.

> More about (1) - if you want to create
>     public interface Releasable {
>         public void release ();
>     }

No!  I do not want that.  If a component belongs to a pool, the
container will simply return it.  The proxy is generated dynamically,
and the container takes care of the GC process.

> and let the dynamic proxy implement this - that is, you do
> a lookup, and you get something back that implements 
> Releasable - then the client must cast the reference it 
> obtained to Releaseable in order to release it (which it 
> must, as it does not know whether the component is pooled or 
> not). So every component interface that does not have a 
> close() method or similar should extend Releasable 
> to avoid a cast. (And since the component can't really 
> implement the method, it should leave it empty.)

I do not want any more work on the client.  Let the container
be smart and the client be dumb.

> And then we're back where we started... With empty release() 
> methods not just in the CM, but all over the place.

No, no, no, no.

You aren't getting it.

The container tracks the instances that it needs to track (i.e. the
pooled instances), and GCs them automatically.  Nothing needs or
should be done by the client.   Period.

To unsubscribe, e-mail:
For additional commands, email:

View raw message