You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Robert Mouat <ro...@mouat.net> on 2002/06/20 23:28:54 UTC

[proposal] custom component lookup

here is a proposal that will allow us to:

  - have a well defined relationship between the container and
  component managers [though it doesn't touch on the issue of
  component resolving]

    + you could write component managers that will work in any
    container - and be specified at assembly time.

    + these new component managers will work alongside the existing
    component managers (allowing for a gentle upgrade path).

  - create dynamic proxies, for example:

    + tracing of component level method calls.

    + aaa (authentication, authorisation, and accounting), an aaa
    proxy could intercept component level method calls.

    + release() via the VM's garbage collector.

    + sessions could be implemented this way (with only slight
    modifications from my recent email).

  - possibly satisfy some of the need for custom markers (as long as
  they are called after initialize). [sessions would probably fit this
  category]

  - chain together any of the above (at the whim of the assembler).

this will work with version 4 (and 5) of the framework and shouldn't
break anything currently in existence.


==== proposal: CustomLookup interface ====

the proposal is simply that we add the following interface to the
framework:

  interface CustomLookup
  {
    public Object lookup();
  }

with the contract:

  if a component implements the CustomLookup interface then upon
  ServiceManager.lookup() a reference to the component is not
  returned, but instead the result of the CustomLookup.lookup()
  method is returned.

e.g. inside the ServiceManager the following:

  return component;

could be replaced with:

  if ( component instanceof CustomLookup )
  {
    return ((CustomLookup) component).lookup();
  } else {
    return component;
  }

Note: the CustomLookup should probably have a release() method that
is deprecated/removed with the ServiceManager.release().

Note: the CustomLookup.lookup() has no args (to prevent it from
being used as a selector/directory/resolver)

I'd also like to make the following recommendation:

  in the absence of any other lifestyle indicator a component
  implementing CustomLookup should be a singleton, otherwise a new
  instance should be created upon every lookup.

Note: the container will still have to be able to handle these two
lifestyles (single and per-lookup) but all others can be managed by
CustomLookup components.

It shouldn't take much effort to implement this change.


==== example: component manager ====

note: component managers get the benefits of the lifecycle methods...

for simplicity: not dealing with synchronization, exceptions, and
assuming that release() will get called.

  class PoolingComponentManager
    implements CustomLookup, Parameterizable, Composable, Initializable
  {
    static final DEFAULT_SIZE = 5;
    String m_role;
    int m_size;
    List m_pool;
    ComponentManager m_cm;

    public void parameterize( Parameters parameters )
    {
      m_size = parameters.getParameterAsInteger( "size", DEFAULT_SIZE );
      m_role = parameters.getParameter( "role", null );
    }

    public void Compose( ComponentManager cm )
    {
      m_cm = cm;
    }

    public void initialize()
    {
      m_pool = new ArrayList( m_size );
    }

    public Object lookup()
    {
      if (! m_pool.isEmpty() )
        return m_pool.remove( 0 );
      else
        return m_cm.lookup( m_role );
    }

    public void release( Object component )
    {
      if ( m_pool.size() < m_size )
      {
        if ( component instanceof Recyclable )
          ((Recyclable) component).recycle();
        m_pool.add( component );
      }
      else
        m_cm.release( component );
    }

  }

To use the PoolingComponentManager on a component X the assembler
could do the following...

  1. configure the pooling component manager so that it has parametes
  role=X-role size=5

  2. configure the component locater so that a lookup that would have
  resolved to X now resolves to the pooling component manager.  And
  that when the pooling component manager looks up X-role it gets X.

Now whenever a client makes a request that would resolve to X, the
request will go to the pooling component manager which will return a
component from its pool or request X-role from the ComponentManager
(if the pool is empty).

==== example: dynamic proxy ====

here is an example of how a tracing proxy could be implemented (minus
exception handling and synchronization)...

  class TracingProxy extends AbstractLogEnabled
    implements CustomLookup, InvocationHandler, Composable, Parameterizable
  {
    String m_role;
    String m_name;
    ComponentManager m_cm;
    Map m_ids = new WeakHashMap();
    int count = 0;

    public void parameterize( Parameters parameters )
    {
      m_role = parameters.getParameter( "role", null );
      m_name = parameters.getParameter( "name", "tracingProxy" );
    }

    public void compose( ComponentManager cm )
    {
      m_cm = cm;
    }

    public Object invoke( Object proxy, Method method, Object[] args )
      throws Throwable
    {
      Object ret;
      Object id = m_ids.get( proxy );
      info( "Enter: " + method + " for " + m_name + "-" + id );
      try
      {
        ret = method.invoke( m_component, args );
      }
      catch ( InvocationTargetException ite )
      {
        warn( "Error in: " + method " for " + m_name + "-" + id, ite );
        throw ite.getTargetException();
      }
      info( "Leave: " + method + " for " + m_name + "-" + id );
      return ret;
    }

    public Object lookup()
    {
      Object component = m_cm.lookup( m_role );
      Class[] interfaces = component.getClass().getInterfaces();
      ClassLoader classLoader = component.getClass().getClassLoader();
      Object proxy = java.lang.reflect.Proxy.newInstance(
        classLoader, interfaces, this
      );
      m_ids.put( proxy, new Integer( ++m_count ) );
      return proxy;
    }

  }


To activate the tracing on a component X the assembler could do the
following...

  1. configure the tracing proxy so that it has parameters:
  role=X-role, name=X-trace

  2. give the tracing proxy its own logger.

  3. configure the component locator so that a lookup that would have
  resolved to X now resolves to the tracing proxy.  And that whenever
  the tracing proxy looks up X-role it gets X.

Now whenever a client makes a request that would resolve to X they
will get a proxy that will log all method calls, before passing them
on.

====

a SessionManagingProxy proxy can be created in a similar fashion to my
recent email, with the change that the Proxy now runs the show (and
the SessionEnabled component should probably let m_SessionManager
default to an instance of SimpleSessionManager in case
setSessionManager() isn't called).

==== issues ====

  - it is now possible for the assembler to specify cyclic
  dependencies when chaining Customlookup components together, this
  may cause lookup() to hang.

  - unless you have something like:

      public Object lookup() { return this; }

   no other component will ever get a direct reference to the
   CustomLookup component.  So I'm wondering if it is still correct to
   refer to it as a component... perhaps meta-component might be
   better... or since the dynamic proxies could fall into a broad
   definition of component management, perhaps manager-component...

  - I don't know if 'CustomLookup' is a great name so feel free
  to suggest others... MetaComponent?

Robert.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: [proposal] custom component lookup

Posted by Robert Mouat <ro...@mouat.net>.
Berin Loritsch wrote:

> > From: Robert Mouat [mailto:robert@mouat.net] 
> > 
> > Michael McKibben wrote:
> > 
> > > Isn't this a chicken-and-the-egg problem? The CM must know which 
> > > component instance to call lookup() on! Perhaps if it was a static 
> > > method that was introspected, but I'm not sure that is a viable 
> > > solution. JNDI has some nifty solutions that might be possible to 
> > > borrow from, e.g. the Referenceable interface and the 
> > > ObjectFactory/ObjectFactoryBuilder.
> > 
> > that's why I suggested that they be singletons (i.e. only one 
> > instance of the component).
> > 
> > however - even if they were given some other lifestyle it 
> > would still work, there would just be redundant instances.
> 
> Keep in mind that there are ways of creating singletons without static
> accessors.  However that gets back to the ThreadSafe argument, which
> is what we are wanting to solve.  Meta Data is the best way of doing
> this.

I did mean 'singletons' in a threadsafe/non-static way.  In fact I was
thinking that you'd want to be able to create several singleton components
from the same class...

e.g. if there are 2 components A and B - and I want to trace method calls
on both of them.  I could create 2 proxy components A-trace and B-trace to
trace the method calls (as per previous email).  A-trace and B-trace would
both be singleton components (there is no need to create more than one
instance) - however they would both be of the class TracingProxy but
configured differently.  Hence static methods wouldn't work very well.

Having said that I would make them singletons - they don't *need* to be
used that way - there is no reason why a new instance of A-trace couldn't
be created every time someone wanted the component A (though this is
probably not going to be the most efficient way of doing things).

Robert.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: [proposal] custom component lookup

Posted by Berin Loritsch <bl...@apache.org>.
> From: Robert Mouat [mailto:robert@mouat.net] 
> 
> Michael McKibben wrote:
> 
> > Isn't this a chicken-and-the-egg problem? The CM must know which 
> > component instance to call lookup() on! Perhaps if it was a static 
> > method that was introspected, but I'm not sure that is a viable 
> > solution. JNDI has some nifty solutions that might be possible to 
> > borrow from, e.g. the Referenceable interface and the 
> > ObjectFactory/ObjectFactoryBuilder.
> 
> that's why I suggested that they be singletons (i.e. only one 
> instance of the component).
> 
> however - even if they were given some other lifestyle it 
> would still work, there would just be redundant instances.


Keep in mind that there are ways of creating singletons without static
accessors.  However that gets back to the ThreadSafe argument, which
is what we are wanting to solve.  Meta Data is the best way of doing
this.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Robert Mouat <ro...@mouat.net>.
Michael McKibben wrote:

> Isn't this a chicken-and-the-egg problem? The CM must know which component
> instance to call lookup() on! Perhaps if it was a static method that was
> introspected, but I'm not sure that is a viable solution. JNDI has some
> nifty solutions that might be possible to borrow from, e.g. the
> Referenceable interface and the ObjectFactory/ObjectFactoryBuilder.

that's why I suggested that they be singletons (i.e. only one instance of
the component).

however - even if they were given some other lifestyle it would still
work, there would just be redundant instances.

Robert.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: [proposal] custom component lookup

Posted by Michael McKibben <mi...@hihat.net>.
On Thu, 20 Jun 2002, Berin Loritsch wrote:
[snip]

> The closer we get to JNDI, the more I will push using JNDI.
> Peter and I have both done implementations of JNDI lookup,
> and it is not that fun.  However, it would make us more
> aligned with J2EE principles.
> 
> As has been pointed out a long time ago, we want to be able
> to define a container that works in a constrained environment.
> That is one of the principle reasons JNDI was ruled out.

Right, I didn't mean to imply to replace the existing framework with
JNDI-- just to take a look at the approach it takes to solving the problem
of what object to return from a lookup(). The interesting thing is that
the object you bind in JNDI does not necessarily equal the object returned
from a lookup(), which is what was being proposed by the CustomLookup
interface.

Regards,
 
--mike


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: [proposal] custom component lookup

Posted by Berin Loritsch <bl...@apache.org>.
> From: Michael McKibben [mailto:mike@hihat.net] 
> 
> Isn't this a chicken-and-the-egg problem? The CM must know 
> which component instance to call lookup() on! Perhaps if it 
> was a static method that was introspected, but I'm not sure 
> that is a viable solution. JNDI has some nifty solutions that 
> might be possible to borrow from, e.g. the Referenceable 
> interface and the ObjectFactory/ObjectFactoryBuilder.

Any solution which uses static accessors to get an instance
will be vetoed on grounds of breaking IOC.  It also makes it
a whole lot more difficult to enforce proper security.

The closer we get to JNDI, the more I will push using JNDI.
Peter and I have both done implementations of JNDI lookup,
and it is not that fun.  However, it would make us more
aligned with J2EE principles.

As has been pointed out a long time ago, we want to be able
to define a container that works in a constrained environment.
That is one of the principle reasons JNDI was ruled out.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Michael McKibben <mi...@hihat.net>.
Isn't this a chicken-and-the-egg problem? The CM must know which component
instance to call lookup() on! Perhaps if it was a static method that was
introspected, but I'm not sure that is a viable solution. JNDI has some
nifty solutions that might be possible to borrow from, e.g. the
Referenceable interface and the ObjectFactory/ObjectFactoryBuilder.

Regards,

--mike

On Thu, 20 Jun 2002, Robert Mouat wrote:

> here is a proposal that will allow us to:
> 
>   - have a well defined relationship between the container and
>   component managers [though it doesn't touch on the issue of
>   component resolving]
> 
>     + you could write component managers that will work in any
>     container - and be specified at assembly time.
> 
>     + these new component managers will work alongside the existing
>     component managers (allowing for a gentle upgrade path).
> 
>   - create dynamic proxies, for example:
> 
>     + tracing of component level method calls.
> 
>     + aaa (authentication, authorisation, and accounting), an aaa
>     proxy could intercept component level method calls.
> 
>     + release() via the VM's garbage collector.
> 
>     + sessions could be implemented this way (with only slight
>     modifications from my recent email).
> 
>   - possibly satisfy some of the need for custom markers (as long as
>   they are called after initialize). [sessions would probably fit this
>   category]
> 
>   - chain together any of the above (at the whim of the assembler).
> 
> this will work with version 4 (and 5) of the framework and shouldn't
> break anything currently in existence.
> 
> 
> ==== proposal: CustomLookup interface ====
> 
> the proposal is simply that we add the following interface to the
> framework:
> 
>   interface CustomLookup
>   {
>     public Object lookup();
>   }
> 
> with the contract:
> 
>   if a component implements the CustomLookup interface then upon
>   ServiceManager.lookup() a reference to the component is not
>   returned, but instead the result of the CustomLookup.lookup()
>   method is returned.
> 
> e.g. inside the ServiceManager the following:
> 
>   return component;
> 
> could be replaced with:
> 
>   if ( component instanceof CustomLookup )
>   {
>     return ((CustomLookup) component).lookup();
>   } else {
>     return component;
>   }
> 
> Note: the CustomLookup should probably have a release() method that
> is deprecated/removed with the ServiceManager.release().
> 
> Note: the CustomLookup.lookup() has no args (to prevent it from
> being used as a selector/directory/resolver)
> 
> I'd also like to make the following recommendation:
> 
>   in the absence of any other lifestyle indicator a component
>   implementing CustomLookup should be a singleton, otherwise a new
>   instance should be created upon every lookup.
> 
> Note: the container will still have to be able to handle these two
> lifestyles (single and per-lookup) but all others can be managed by
> CustomLookup components.
> 
> It shouldn't take much effort to implement this change.
> 
> 
> ==== example: component manager ====
> 
> note: component managers get the benefits of the lifecycle methods...
> 
> for simplicity: not dealing with synchronization, exceptions, and
> assuming that release() will get called.
> 
>   class PoolingComponentManager
>     implements CustomLookup, Parameterizable, Composable, Initializable
>   {
>     static final DEFAULT_SIZE = 5;
>     String m_role;
>     int m_size;
>     List m_pool;
>     ComponentManager m_cm;
> 
>     public void parameterize( Parameters parameters )
>     {
>       m_size = parameters.getParameterAsInteger( "size", DEFAULT_SIZE );
>       m_role = parameters.getParameter( "role", null );
>     }
> 
>     public void Compose( ComponentManager cm )
>     {
>       m_cm = cm;
>     }
> 
>     public void initialize()
>     {
>       m_pool = new ArrayList( m_size );
>     }
> 
>     public Object lookup()
>     {
>       if (! m_pool.isEmpty() )
>         return m_pool.remove( 0 );
>       else
>         return m_cm.lookup( m_role );
>     }
> 
>     public void release( Object component )
>     {
>       if ( m_pool.size() < m_size )
>       {
>         if ( component instanceof Recyclable )
>           ((Recyclable) component).recycle();
>         m_pool.add( component );
>       }
>       else
>         m_cm.release( component );
>     }
> 
>   }
> 
> To use the PoolingComponentManager on a component X the assembler
> could do the following...
> 
>   1. configure the pooling component manager so that it has parametes
>   role=X-role size=5
> 
>   2. configure the component locater so that a lookup that would have
>   resolved to X now resolves to the pooling component manager.  And
>   that when the pooling component manager looks up X-role it gets X.
> 
> Now whenever a client makes a request that would resolve to X, the
> request will go to the pooling component manager which will return a
> component from its pool or request X-role from the ComponentManager
> (if the pool is empty).
> 
> ==== example: dynamic proxy ====
> 
> here is an example of how a tracing proxy could be implemented (minus
> exception handling and synchronization)...
> 
>   class TracingProxy extends AbstractLogEnabled
>     implements CustomLookup, InvocationHandler, Composable, Parameterizable
>   {
>     String m_role;
>     String m_name;
>     ComponentManager m_cm;
>     Map m_ids = new WeakHashMap();
>     int count = 0;
> 
>     public void parameterize( Parameters parameters )
>     {
>       m_role = parameters.getParameter( "role", null );
>       m_name = parameters.getParameter( "name", "tracingProxy" );
>     }
> 
>     public void compose( ComponentManager cm )
>     {
>       m_cm = cm;
>     }
> 
>     public Object invoke( Object proxy, Method method, Object[] args )
>       throws Throwable
>     {
>       Object ret;
>       Object id = m_ids.get( proxy );
>       info( "Enter: " + method + " for " + m_name + "-" + id );
>       try
>       {
>         ret = method.invoke( m_component, args );
>       }
>       catch ( InvocationTargetException ite )
>       {
>         warn( "Error in: " + method " for " + m_name + "-" + id, ite );
>         throw ite.getTargetException();
>       }
>       info( "Leave: " + method + " for " + m_name + "-" + id );
>       return ret;
>     }
> 
>     public Object lookup()
>     {
>       Object component = m_cm.lookup( m_role );
>       Class[] interfaces = component.getClass().getInterfaces();
>       ClassLoader classLoader = component.getClass().getClassLoader();
>       Object proxy = java.lang.reflect.Proxy.newInstance(
>         classLoader, interfaces, this
>       );
>       m_ids.put( proxy, new Integer( ++m_count ) );
>       return proxy;
>     }
> 
>   }
> 
> 
> To activate the tracing on a component X the assembler could do the
> following...
> 
>   1. configure the tracing proxy so that it has parameters:
>   role=X-role, name=X-trace
> 
>   2. give the tracing proxy its own logger.
> 
>   3. configure the component locator so that a lookup that would have
>   resolved to X now resolves to the tracing proxy.  And that whenever
>   the tracing proxy looks up X-role it gets X.
> 
> Now whenever a client makes a request that would resolve to X they
> will get a proxy that will log all method calls, before passing them
> on.
> 
> ====
> 
> a SessionManagingProxy proxy can be created in a similar fashion to my
> recent email, with the change that the Proxy now runs the show (and
> the SessionEnabled component should probably let m_SessionManager
> default to an instance of SimpleSessionManager in case
> setSessionManager() isn't called).
> 
> ==== issues ====
> 
>   - it is now possible for the assembler to specify cyclic
>   dependencies when chaining Customlookup components together, this
>   may cause lookup() to hang.
> 
>   - unless you have something like:
> 
>       public Object lookup() { return this; }
> 
>    no other component will ever get a direct reference to the
>    CustomLookup component.  So I'm wondering if it is still correct to
>    refer to it as a component... perhaps meta-component might be
>    better... or since the dynamic proxies could fall into a broad
>    definition of component management, perhaps manager-component...
> 
>   - I don't know if 'CustomLookup' is a great name so feel free
>   to suggest others... MetaComponent?
> 
> Robert.
> 
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
> 


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Robert Mouat <ro...@mouat.net>.
Peter Donald wrote:

> At 05:02 PM 6/21/2002 -0700, you wrote:
> >Peter Donald wrote:
> >
> > > >but I also was wondering if there is any container extension mechanism
> > > >that is shared by the Avalon containers - or if there are plans for
> > > >anything like that?
> > >
> > > It would be neat to have a generic interceptor architecture. For a
> > > buisness-esque type layer you could have interceptor interface such as
> > >
> > > interface Interceptor
> > > {
> > >    Object invoke( InterceptorContext ctx, Object[] args ) throws Exception;
> > > }
> > >
> > > interface InterceptorContext
> > > {
> > >    ComponentMetaData getCaller();
> > >    ComponentMetaData getCallee();
> > >    DependencyMetaData getCalledInterface();
> > >    String getMethodSignature();
> > >
> > >    Object invokeNext( Object[] args ) throws Exception;
> > > }
> 
> >I have a couple questions about this Interceptor...
> >
> >1. would it be a component? i.e. do you imagine it being looked up like
> >other components?  This seems like it would be a good idea, e.g. in the
> >case of the AuthorizingInterceptor you described, it might be handy if
> >another component could look it up and set some security settings.
> 
> It could be (up to the container) but I would probably not make it 
> accessible that way. The Interceptor may be able to lookup another 
> component and read security settings or have a component create it and the 
> creator lookup another component. At least that is how I would do it.

For the interceptor to look up another component would imply it implments
Composable -- and allowing it to implement other lifecycle methods would
not be a bad thing --- I guess it could be an 'invisible component'
(i.e. can't be looked up by other components).

As for having another component create the interceptor, this would require
that component to have an extra 'hook' into the container (to tell the
container to use the interceptor) -- I was thinking more along the lines
that interceptors would be specified in the configuration/assembly.

> 2. Does this Interceptor interface have any benefits over dynamic proxies?
> >[the container will need to generate a dynamic proxy to intercept the
> >calls in order to pass them onto the interceptor].
> 
> I would have a single dynamic proxy reference multiple Interceptors as 
> dynamic proxies instantiation are likely to be more expensive than 
> Interceptor instantiation.

that makes sense, and would also allow for dynamically changing the
interceptors.

Robert.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Peter Donald <pe...@apache.org>.
At 05:02 PM 6/21/2002 -0700, you wrote:
>Peter Donald wrote:
>
> > >but I also was wondering if there is any container extension mechanism
> > >that is shared by the Avalon containers - or if there are plans for
> > >anything like that?
> >
> > It would be neat to have a generic interceptor architecture. For a
> > buisness-esque type layer you could have interceptor interface such as
> >
> > interface Interceptor
> > {
> >    Object invoke( InterceptorContext ctx, Object[] args ) throws Exception;
> > }
> >
> > interface InterceptorContext
> > {
> >    ComponentMetaData getCaller();
> >    ComponentMetaData getCallee();
> >    DependencyMetaData getCalledInterface();
> >    String getMethodSignature();
> >
> >    Object invokeNext( Object[] args ) throws Exception;
> > }
>
>this is actually closer to what I was originally thinking -- I was
>thinking about a generic mechanism to allow for dynamic proxies -- my
>original idea was to have a component implement a subclass of
>InvocationHandler, then have the container create a proxy from the
>InvocationHandler each lookup... but then I thought that allowing the
>component to implement a lookup() method might be more flexible... but
>then I wondered if this might be too flexible since it would step on the
>toes of the component manager.... but I digress :)


:)

>I have a couple questions about this Interceptor...
>
>1. would it be a component? i.e. do you imagine it being looked up like
>other components?  This seems like it would be a good idea, e.g. in the
>case of the AuthorizingInterceptor you described, it might be handy if
>another component could look it up and set some security settings.

It could be (up to the container) but I would probably not make it 
accessible that way. The Interceptor may be able to lookup another 
component and read security settings or have a component create it and the 
creator lookup another component. At least that is how I would do it.

2. Does this Interceptor interface have any benefits over dynamic proxies?
>[the container will need to generate a dynamic proxy to intercept the
>calls in order to pass them onto the interceptor].

I would have a single dynamic proxy reference multiple Interceptors as 
dynamic proxies instantiation are likely to be more expensive than 
Interceptor instantiation.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Leo Simons <le...@apache.org>.
Essentially take those graphs I made, then replace DependencyMap with
the interceptor pattern of doing things. Could also see it as a chain or
pipeline. Right?

When generalized, this probably adds quite a bit of complexity to the
container and maybe quite a bit of slowdown as well during lookup.

Also, conceptually replacing "a simple, one-method, one-arg, hash-backed
lookup()" with a "chain of responsibility to satisfy any style of
lookup()" is pretty bad.

So I would not generalize it. Then it can have obvious advantages.

regards,

- Leo

> I remember the suggestion - but I'm thinking about this differently in 
> terms of an interceptor architecture.  Basically, an interceptor 
> approach on a container would provide a more general solution to 
> componet selection that Leo and I were discussing.  My current working 
> solution is to locate a selector using a pluggable service class 
> selector (which was easy to do but has many restrictions) - and Leo 
> specifically wanted to things that went beyond service type.  Adding the 
> notion of an interceptor chain between the container and any client of 
> the container (e.g. a component manager/locator) would enable a lot more 
> flexibility and would alow things like a component transaction to be 
> hidden within an interceptor implementation.  It would also open up a 
> lot more flexibility in terms of strict compliance with formal component 
> contracts - i.e. an ECMInterceptor could handle parsing and 
> interpritation of a Cocoon style lookup, handle all of that stuff 
> related to hints selectors etc. - effectively seperating the Cocoon 
> usage model from the container.  As to the pooling stuff - I don't have 
> a good idea of what that would involve but I have a hunch that it could 
> be practicel approach - at least it would be interesting to get 
> throughts in this from members of the list that are heavily into pooled 
> objects.
> 
> Cheers, Steve.
> 
> p.s. Can you do me a favour and repost the earlier message concerning 
> (Component)Transaction.
> 
> SJM
> 
> >
> >
> > Cheers,
> >
> > Peter Donald
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > "Faced with the choice between changing one's mind,
> > and proving that there is no need to do so - almost
> > everyone gets busy on the proof."
> >              - John Kenneth Galbraith
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >
> >
> > -- 
> > To unsubscribe, e-mail:   
> > <ma...@jakarta.apache.org>
> > For additional commands, e-mail: 
> > <ma...@jakarta.apache.org>
> >
> 
> -- 
> 
> Stephen J. McConnell
> 
> OSM SARL
> digital products for a global economy
> mailto:mcconnell@osm.net
> http://www.osm.net
> 
> 
> 
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
> 




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Peter Donald <pe...@apache.org>.
At 07:56 AM 6/21/2002 +0200, you wrote:
>>Transparent pooling via proxies? I thought about that earlier but it 
>>requires the notion of a (Component)Transaction which I mentioned a while 
>>back that no one seemed to like.
>
>
>I remember the suggestion - but I'm thinking about this differently in 
>terms of an interceptor architecture.

Hmm Interceptor architectures are generally tied to method invocation 
models not to lookup of a component. So interceptors only come into play 
after a service has been looked up. (At least in most ORB based 
architecutres from J2EE, CORBA and MSes enterprise object system .. not DNA 
whats it called nowadays?).

So the way I see it being used is as follows. We have a transaction 
interceptor that associates a transaction with the current call (lets 
ignore the policy for this atm). Then we have an interceptor that does 
something like the following;

interface ResourceReleaser
{
   void release();
}

class PoolingInterceptor implements Interceptor, ResourceReleaser
{
   private Object m_object;

   Object invoke( InterceptorContext ctx, Object[] args ) throws Exception
   {
      if( null == m_object )
      {
         //Okay this resource not used yet in this transaction
         //so lets try and aquire it and associate with transaction
         m_object = getPool().getInstance();
         m_object.activate();
         getComponentTransaction().addResource( m_object, 
(ResourceReleaser)this );
      }

      return m_object.invoke( ctx.getMethod(), args );
   }

   void release()
   {
      //This is called when transaction ends, or request goes out of scope or
      //transaction is finished
      m_object.deactivate();
      getPool().release( m_object );
   }
}

So the first time the client tries to call a method on object it is 
retriewved from pool. As soon as the transaction is finished, the request 
ends or the client goes out of scope via some other method then the object 
is released. Activate()/deactivate() are the called to prep it after coming 
out of pool or before going back in.

Basically this is hald of what EJB servers do to get scalability. I don't 
know if it is common among CORBA apps (Stephen?) but it is fairly well 
developed technique. Easy to write components but fairly hard to write the 
container.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Stephen McConnell <mc...@osm.net>.

Peter Donald wrote:

> At 07:04 AM 6/21/2002 +0200, you wrote:
> Ummmm, ... just thinking out load
>
>>  class ECMInterceptor implements Interceptor
>>  {
>>   ....
>>  }
>>
>>
>>  class PooInterceptor implements Interceptor
>>  {
>>   ....
>>  }
>
>
> Transparent pooling via proxies? I thought about that earlier but it 
> requires the notion of a (Component)Transaction which I mentioned a 
> while back that no one seemed to like.


I remember the suggestion - but I'm thinking about this differently in 
terms of an interceptor architecture.  Basically, an interceptor 
approach on a container would provide a more general solution to 
componet selection that Leo and I were discussing.  My current working 
solution is to locate a selector using a pluggable service class 
selector (which was easy to do but has many restrictions) - and Leo 
specifically wanted to things that went beyond service type.  Adding the 
notion of an interceptor chain between the container and any client of 
the container (e.g. a component manager/locator) would enable a lot more 
flexibility and would alow things like a component transaction to be 
hidden within an interceptor implementation.  It would also open up a 
lot more flexibility in terms of strict compliance with formal component 
contracts - i.e. an ECMInterceptor could handle parsing and 
interpritation of a Cocoon style lookup, handle all of that stuff 
related to hints selectors etc. - effectively seperating the Cocoon 
usage model from the container.  As to the pooling stuff - I don't have 
a good idea of what that would involve but I have a hunch that it could 
be practicel approach - at least it would be interesting to get 
throughts in this from members of the list that are heavily into pooled 
objects.

Cheers, Steve.

p.s. Can you do me a favour and repost the earlier message concerning 
(Component)Transaction.

SJM

>
>
> Cheers,
>
> Peter Donald
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> "Faced with the choice between changing one's mind,
> and proving that there is no need to do so - almost
> everyone gets busy on the proof."
>              - John Kenneth Galbraith
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>
> -- 
> To unsubscribe, e-mail:   
> <ma...@jakarta.apache.org>
> For additional commands, e-mail: 
> <ma...@jakarta.apache.org>
>

-- 

Stephen J. McConnell

OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Peter Donald <pe...@apache.org>.
At 03:33 PM 6/21/2002 +1000, you wrote:
>At 07:04 AM 6/21/2002 +0200, you wrote:
>Ummmm, ... just thinking out load
>
>>  class ECMInterceptor implements Interceptor
>>  {
>>   ....
>>  }
>>
>>
>>  class PooInterceptor implements Interceptor
>>  {
>>   ....
>>  }
>
>Transparent pooling via proxies? I thought about that earlier but it 
>requires the notion of a (Component)Transaction which I mentioned a while 
>back that no one seemed to like.

Then again it would fit in with the "J2EE style" of implementing things so 
maybe its an option.


Cheers,

Peter Donald
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"Faced with the choice between changing one's mind,
and proving that there is no need to do so - almost
everyone gets busy on the proof."
              - John Kenneth Galbraith
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Peter Donald <pe...@apache.org>.
At 07:04 AM 6/21/2002 +0200, you wrote:
Ummmm, ... just thinking out load

>  class ECMInterceptor implements Interceptor
>  {
>   ....
>  }
>
>
>  class PooInterceptor implements Interceptor
>  {
>   ....
>  }

Transparent pooling via proxies? I thought about that earlier but it 
requires the notion of a (Component)Transaction which I mentioned a while 
back that no one seemed to like.


Cheers,

Peter Donald
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"Faced with the choice between changing one's mind,
and proving that there is no need to do so - almost
everyone gets busy on the proof."
              - John Kenneth Galbraith
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Stephen McConnell <mc...@osm.net>.

Peter Donald wrote:

> At 08:54 PM 6/20/2002 -0700, you wrote:
>
>> Peter Donald wrote:
>> ok, I actually forgot to put in a sentence/disclaimer at the end
>> mentioning that it might possibly be more of an implementation thing 
>> than
>> a framework thing...
>
>
> ;)
>
>> but I also was wondering if there is any container extension mechanism
>> that is shared by the Avalon containers - or if there are plans for
>> anything like that?
>
>
> It would be neat to have a generic interceptor architecture. For a 
> buisness-esque type layer you could have interceptor interface such as
>
> interface Interceptor
> {
>   Object invoke( InterceptorContext ctx, Object[] args ) throws 
> Exception;
> }
>
> interface InterceptorContext
> {
>   ComponentMetaData getCaller();
>   ComponentMetaData getCallee();
>   DependencyMetaData getCalledInterface();
>   String getMethodSignature();
>
>   Object invokeNext( Object[] args ) throws Exception;
> }
>
> Possible impls...
>
> class MyAuthorizingInterceptor implements Interceptor
> {
>   Object invoke( InterceptorContext ctx, Object[] args ) throws Exception
>   {
>      if( !isAuthorized( ctx.getCaller() ) ) throw 
> SecurityException("...");
>      return ctx.invokeNext( args );
>   }
> }
>
> class MyTimingInterceptor implements Interceptor
> {
>   Object invoke( InterceptorContext ctx, Object[] args ) throws Exception
>   {
>      final long key = startTimer();
>
>      try { return ctx.invokeNext( args ); }
>      finally
>      {
>       final long time = endTimer( key );
>       reportTime( time );
>      }
>   }
> }
>
> This would be particular useful to people who are using Avalon for 
> Buisness level prgramming (in contrast to System-level programming). 


Ummmm, ... just thinking out load

  class ECMInterceptor implements Interceptor
  {
   ....
  }


  class PooInterceptor implements Interceptor
  {
   ....
  }

Steve.


>
>
> However I don't know of any plans to implement this unless you want to 
> volunteer ;)
>
>
>
> Cheers,
>
> Peter Donald
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> "Faced with the choice between changing one's mind,
> and proving that there is no need to do so - almost
> everyone gets busy on the proof."
>              - John Kenneth Galbraith
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>
> -- 
> To unsubscribe, e-mail:   
> <ma...@jakarta.apache.org>
> For additional commands, e-mail: 
> <ma...@jakarta.apache.org>
>

-- 

Stephen J. McConnell

OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Robert Mouat <ro...@mouat.net>.
Peter Donald wrote:

> >but I also was wondering if there is any container extension mechanism
> >that is shared by the Avalon containers - or if there are plans for
> >anything like that?
> 
> It would be neat to have a generic interceptor architecture. For a 
> buisness-esque type layer you could have interceptor interface such as
> 
> interface Interceptor
> {
>    Object invoke( InterceptorContext ctx, Object[] args ) throws Exception;
> }
> 
> interface InterceptorContext
> {
>    ComponentMetaData getCaller();
>    ComponentMetaData getCallee();
>    DependencyMetaData getCalledInterface();
>    String getMethodSignature();
> 
>    Object invokeNext( Object[] args ) throws Exception;
> }

this is actually closer to what I was originally thinking -- I was
thinking about a generic mechanism to allow for dynamic proxies -- my
original idea was to have a component implement a subclass of
InvocationHandler, then have the container create a proxy from the
InvocationHandler each lookup... but then I thought that allowing the
component to implement a lookup() method might be more flexible... but
then I wondered if this might be too flexible since it would step on the
toes of the component manager.... but I digress :)


I have a couple questions about this Interceptor...

1. would it be a component? i.e. do you imagine it being looked up like
other components?  This seems like it would be a good idea, e.g. in the
case of the AuthorizingInterceptor you described, it might be handy if
another component could look it up and set some security settings.


2. Does this Interceptor interface have any benefits over dynamic proxies?  
[the container will need to generate a dynamic proxy to intercept the
calls in order to pass them onto the interceptor].

  e.g. the same result could be achieved with:

    interface ProxyHandler implements InvocationHandler
    {

      public void associateContext(
          Object proxy,
          ComponentMetaData caller,
          ComponentMetaData callee,
          Object next
       );

      // from InvocationHandler
      public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable;

    }

    where the proxy the container creates is passed in to the
    associateContext method.  And to pass the method on the invoke method
    could do:

      Context ctx = (Context) m_contexts.get( proxy );
      result = method.invoke( ctx.getNext(), args );


> Possible impls...
> 
> class MyAuthorizingInterceptor implements Interceptor
> {
>    Object invoke( InterceptorContext ctx, Object[] args ) throws Exception
>    {
>       if( !isAuthorized( ctx.getCaller() ) ) throw SecurityException("...");
>       return ctx.invokeNext( args );
>    }
> }
> 
> class MyTimingInterceptor implements Interceptor
> {
>    Object invoke( InterceptorContext ctx, Object[] args ) throws Exception
>    {
>       final long key = startTimer();
> 
>       try { return ctx.invokeNext( args ); }
>       finally
>       {
>        final long time = endTimer( key );
>        reportTime( time );
>       }
>    }
> }
> 
> This would be particular useful to people who are using Avalon for Buisness 
> level prgramming (in contrast to System-level programming).
> 
> However I don't know of any plans to implement this unless you want to 
> volunteer ;)

unfortunately not until after I finish writing my thesis...

Robert (who avoids writing his thesis by hanging out on avalon-dev :).


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Peter Donald <pe...@apache.org>.
At 08:54 PM 6/20/2002 -0700, you wrote:
>Peter Donald wrote:
>ok, I actually forgot to put in a sentence/disclaimer at the end
>mentioning that it might possibly be more of an implementation thing than
>a framework thing...

;)

>but I also was wondering if there is any container extension mechanism
>that is shared by the Avalon containers - or if there are plans for
>anything like that?

It would be neat to have a generic interceptor architecture. For a 
buisness-esque type layer you could have interceptor interface such as

interface Interceptor
{
   Object invoke( InterceptorContext ctx, Object[] args ) throws Exception;
}

interface InterceptorContext
{
   ComponentMetaData getCaller();
   ComponentMetaData getCallee();
   DependencyMetaData getCalledInterface();
   String getMethodSignature();

   Object invokeNext( Object[] args ) throws Exception;
}

Possible impls...

class MyAuthorizingInterceptor implements Interceptor
{
   Object invoke( InterceptorContext ctx, Object[] args ) throws Exception
   {
      if( !isAuthorized( ctx.getCaller() ) ) throw SecurityException("...");
      return ctx.invokeNext( args );
   }
}

class MyTimingInterceptor implements Interceptor
{
   Object invoke( InterceptorContext ctx, Object[] args ) throws Exception
   {
      final long key = startTimer();

      try { return ctx.invokeNext( args ); }
      finally
      {
       final long time = endTimer( key );
       reportTime( time );
      }
   }
}

This would be particular useful to people who are using Avalon for Buisness 
level prgramming (in contrast to System-level programming).

However I don't know of any plans to implement this unless you want to 
volunteer ;)



Cheers,

Peter Donald
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"Faced with the choice between changing one's mind,
and proving that there is no need to do so - almost
everyone gets busy on the proof."
              - John Kenneth Galbraith
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Robert Mouat <ro...@mouat.net>.
Peter Donald wrote:

> At 02:28 PM 6/20/2002 -0700, you wrote:
> >here is a proposal that will allow us to:
> >
> >   - have a well defined relationship between the container and
> >   component managers [though it doesn't touch on the issue of
> >   component resolving]
> >
> >     + you could write component managers that will work in any
> >     container - and be specified at assembly time.
> >
> >     + these new component managers will work alongside the existing
> >     component managers (allowing for a gentle upgrade path).
> >
> >   - create dynamic proxies, for example:
> >
> >     + tracing of component level method calls.
> >
> >     + aaa (authentication, authorisation, and accounting), an aaa
> >     proxy could intercept component level method calls.
> >
> >     + release() via the VM's garbage collector.
> >
> >     + sessions could be implemented this way (with only slight
> >     modifications from my recent email).
> >
> >   - possibly satisfy some of the need for custom markers (as long as
> >   they are called after initialize). [sessions would probably fit this
> >   category]
> >
> >   - chain together any of the above (at the whim of the assembler).
> 
> These are neat features and some containers already implement them. However 
> I don't see any need for them to be associated with lookup mechanism.

ok, I actually forgot to put in a sentence/disclaimer at the end
mentioning that it might possibly be more of an implementation thing than
a framework thing...

but I also was wondering if there is any container extension mechanism
that is shared by the Avalon containers - or if there are plans for
anything like that?

Robert.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [proposal] custom component lookup

Posted by Peter Donald <pe...@apache.org>.
At 02:28 PM 6/20/2002 -0700, you wrote:
>here is a proposal that will allow us to:
>
>   - have a well defined relationship between the container and
>   component managers [though it doesn't touch on the issue of
>   component resolving]
>
>     + you could write component managers that will work in any
>     container - and be specified at assembly time.
>
>     + these new component managers will work alongside the existing
>     component managers (allowing for a gentle upgrade path).
>
>   - create dynamic proxies, for example:
>
>     + tracing of component level method calls.
>
>     + aaa (authentication, authorisation, and accounting), an aaa
>     proxy could intercept component level method calls.
>
>     + release() via the VM's garbage collector.
>
>     + sessions could be implemented this way (with only slight
>     modifications from my recent email).
>
>   - possibly satisfy some of the need for custom markers (as long as
>   they are called after initialize). [sessions would probably fit this
>   category]
>
>   - chain together any of the above (at the whim of the assembler).

These are neat features and some containers already implement them. However 
I don't see any need for them to be associated with lookup mechanism.

As a side note it looks very similar to the notion of interceptors that is 
present in both CORBA and J2EE servers. The interceptors could be 
clientside or serverside and essentially decorate the call or context of 
call in some way.

However interceptors are independent of lookup mechanism even in J2EE. ie 
use JNDI for lookup/directory services and the thing looked up is a 
proxy/stub that implements interceptors internally.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>