cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Robert Mouat <rob...@mouat.net>
Subject Re: [Design] ContainerManager is under fire--let's find the best resolution
Date Fri, 07 Jun 2002 22:42:37 GMT
It's been 6 hours so I'll try posting again...

<delurk/>

On Thu, 6 Jun 2002, Berin Loritsch wrote:

<snip/>

> interface ComponentManager
> {
>     Object lookup(String role);
>     Object lookup(String role, Object hint);
>     boolean exists(String role);
>     boolean exists(String role, Object hint);
> }
> 
> If you notice, there are four distinct differences from the current
> ComponentManger:

<snip/>

> 4) We remove the release() method altogether.

With a combination of dynamic proxies and the Object.finalize() method
it should be possible to use the VM's garbage collector to release a
component.  This would be transparent to both the client and the
component.

how this could work:

- cm.lookup() returns a dynamix proxy implementing the interfaces of
the desired component.  This proxy will pass all interface calls onto
the real component.

- neither the container nor the component manager keep a reference to
the proxy (they are allowed a weak reference -- but we want the VM's
GC to tell us when the client nolonger holds a reference to it.

- the client uses the component (transparently via the proxy).

- when the client loses all references to the proxy the GC will call
the finalize() mothod on the proxy.  This method will do what the
cm.release() method currently does.

[note: it is the proxy that gets garbage collected, not the component]


how the code might look:

class ReleasingProxy implements java.lang.reflect.InvocationHandler
{

  private Object component;

  public ReleasingProxy( Object o )
  {
    component = o;
  }

  public Object invoke( Object proxy, Method method, Object[] args ) 
    throws Throwable
  {
    try
    {
      return method.invoke( component, args );
    }
    catch ( InvocationTargetException e )
    {
      throw e.getTargetException();
    }
  }  

  protected void finalize()
  {
    // code from cm.release() goes here.
  }

}


in the lookup code 'return component;' can be replaced with:

  // may want to filter out the lifecycle interfaces...
  // they don't hurt, but it might be nice if they weren't
  // exposed to the client
  Class[] interfaces = component.getClass().getInterfaces();

  return java.lang.reflect.Proxy.newProxyInstance(
      classLoader,
      interfaces,
      new ReleasingProxy( component )
    );

[note: the ReleasingProxy will probably also need a reference to the
Container for doing the release]

Advantages:

- everything happens transparently to the client and the component

- the release code is only called after the client has lost all
references to the proxy (this actually makes it safer than using
cm.release())

Disadvantages:

- the release code is only called after the client has lost all
references to the proxy.

- relies on the VM's GC to return the component to the pool, and it is
unclear how long this will take.  [I don't know much about GC
implementations, but theoretically if there are no circular references
the reference count can become 0 and the VM can remove the object
immediately]

- requires JDK 1.3

- adds extra indirection to each component method call, and creates a
couple of objects each lookup

Robert.



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


Mime
View raw message