You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by bl...@apache.org on 2002/08/16 05:09:24 UTC

cvs commit: jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/resource PooledLifestyleHandler.java DefaultLifestyleManager.java

bloritsch    2002/08/15 20:09:24

  Modified:    assembly/src/java/org/apache/excalibur/merlin/kernel
                        DefaultKernel.java
               assembly/src/java/org/apache/excalibur/merlin/resource
                        DefaultLifestyleManager.java
  Added:       assembly/src/java/org/apache/excalibur/merlin/resource
                        PooledLifestyleHandler.java
  Log:
  add support for PooledLifestyleHandler
  
  Revision  Changes    Path
  1.38      +64 -27    jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java
  
  Index: DefaultKernel.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -u -r1.37 -r1.38
  --- DefaultKernel.java	13 Aug 2002 05:12:29 -0000	1.37
  +++ DefaultKernel.java	16 Aug 2002 03:09:24 -0000	1.38
  @@ -93,25 +93,29 @@
   import org.apache.excalibur.merlin.container.ContainerFactory;
   import org.apache.excalibur.merlin.resource.LifestyleManager;
   import org.apache.excalibur.merlin.resource.DefaultLifestyleManager;
  +import org.apache.excalibur.event.command.TPCThreadManager;
  +import org.apache.excalibur.event.command.CommandManager;
  +import org.apache.excalibur.mpool.PoolManager;
  +import org.apache.excalibur.mpool.DefaultPoolManager;
   
   /**
    * Default kernel implementation.
    * <p><b>UML</b></p>
    * <p><image src="doc-files/DefaultKernel.gif" border="0"/></p>
    * <p><b>Code Example</b></p>
  - * <p>The following code fragment demonstrates the creation and startup of a new 
  + * <p>The following code fragment demonstrates the creation and startup of a new
    * kernel instance.</P>
    * <pre>
  -   
  +
           <font color="gray">//
           // create the execution context
           //</font>
  -  
  +
           File <strong>base</strong> = new File( <font color="darkred"/>&quot;.&quot;</font> );
           DefaultContext <strong>context</strong> = new DefaultContext();
           <strong>context</strong>.put( DefaultKernel.DIR_KEY, <strong>base</strong> );
           <strong>context</strong>.makeReadOnly();
  -       
  +
           <font color="gray">//
           // Read in the configuration.
           //</font>
  @@ -133,10 +137,10 @@
           <strong>kernel</strong>.initialize();
   
           <font color="gray">//
  -        // Component assembly and resource descriptior assignment is completed during 
  -        // the initialization phase.  Services exported by the kernel may 
  -        // may be access via {@link Resource} references exposed by the 
  -        // {link #getResources()} method.  The following method starts all resources 
  +        // Component assembly and resource descriptior assignment is completed during
  +        // the initialization phase.  Services exported by the kernel may
  +        // may be access via {@link Resource} references exposed by the
  +        // {link #getResources()} method.  The following method starts all resources
           // declared as activatable on startup.
           //</font>
   
  @@ -149,7 +153,7 @@
    * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
    * @version $Revision$ $Date$
    */
  -public class DefaultKernel 
  +public class DefaultKernel
     implements Kernel, Contextualizable, Configurable, Initializable, Startable, Disposable
   {
       //=======================================================================
  @@ -186,6 +190,10 @@
   
       private XMLContainerUtil m_creator = new XMLContainerUtil();
   
  +    private TPCThreadManager m_threadManager;
  +    private CommandManager m_commandManager;
  +    private PoolManager m_poolManager;
  +
      /**
       * Internal reference to the thread within which the root container will execute.
       */
  @@ -198,7 +206,7 @@
   
      /**
       * Flag indicating is this kernel is really a root kernel or a kernel embeded in
  -    * another container.  If we are embeded then logging information is realative 
  +    * another container.  If we are embeded then logging information is realative
       * otherwise the kernel's root container logs at top level.
       */
       private boolean m_root = true;
  @@ -224,7 +232,7 @@
       private String m_name;
   
      /**
  -    * The logging manager that we use to construct logging catagories 
  +    * The logging manager that we use to construct logging catagories
       * and logging channels.
       */
       private static DefaultLoggerManager m_logging;
  @@ -241,11 +249,11 @@
       //=======================================================================
   
      /**
  -    * Invoked by the bootstrap process to supply the root directory and 
  +    * Invoked by the bootstrap process to supply the root directory and
       * optional a path identifying the name of the root container.
       *
       * @param context the context object containing the inital parameters
  -    * @exception ContextException if the supplied does not contain a 
  +    * @exception ContextException if the supplied does not contain a
       *   DIR_KEY value.
       */
       public void contextualize( Context context ) throws ContextException
  @@ -274,7 +282,7 @@
           String name = config.getAttribute("name");
   
           //
  -        // If this kernel has been created inside container scope then 
  +        // If this kernel has been created inside container scope then
           // all we need to do is to setup a root container that the client
           // can access.
           //
  @@ -305,7 +313,7 @@
   
           try
           {
  -            LoggingDescriptor logging = 
  +            LoggingDescriptor logging =
                 m_creator.createLoggingDescriptor( m_config.getChild("logging"), name );
               m_logging = new DefaultLoggerManager( logging );
               m_base = name;
  @@ -315,35 +323,62 @@
               //
   
               Configuration categoriesConfig = config.getChild("categories" );
  -            CategoriesDescriptor categories = 
  +            CategoriesDescriptor categories =
                     m_creator.createCategoriesDescriptor( m_base, categoriesConfig );
               getLoggingManager().addCategories( m_base, categories );
               m_logger = getLoggingManager().getLoggerForCategory( m_base );
               m_localLogger = m_logger.getChildLogger("kernel");
   
               //
  +            // Set up the ThreadManager that the CommandManager uses
  +            //
  +            m_threadManager = new TPCThreadManager();
  +            m_threadManager.enableLogging( getLogger().getChildLogger("threadmanager") );
  +            Parameters params = new Parameters();
  +            params.setParameter( "threads-per-processor", "2" );
  +            params.setParameter( "sleep-time", "1000" );
  +            params.setParameter( "block-timeout", "250" );
  +            m_threadManager.parameterize( params );
  +            m_threadManager.initialize();
  +
  +            //
  +            // Set up the CommandManager that the PoolManager uses.
  +            //
  +            m_commandManager = new CommandManager();
  +            m_threadManager.register( m_commandManager );
  +
  +            //
  +            // Set up the PoolManager that the pooled lifecycle helper needs
  +            //
  +            m_poolManager = new DefaultPoolManager( m_commandManager.getCommandQueue() );
  +
  +            //
               // Independently of any declare lifestyle manager, make sure
  -            // the default lifestyle manager is declared at the kernel 
  -            // level.  Customized managers may appear at the root container 
  -            // level and override the derault.  If not custom mananager is 
  +            // the default lifestyle manager is declared at the kernel
  +            // level.  Customized managers may appear at the root container
  +            // level and override the derault.  If not custom mananager is
               // defined, then system defaults will apply
               //
   
               DefaultLifestyleManager dlm = new DefaultLifestyleManager();
               dlm.enableLogging( getLogger().getChildLogger("lifestyle") );
  +            DefaultContext dlmContext = new DefaultContext();
  +            dlmContext.put( "pool-manager", m_poolManager );
  +            dlmContext.makeReadOnly();
  +            dlm.contextualize( dlmContext );
               dlm.configure( m_config.getChild("lifestyles") );
               dlm.initialize();
   
               //
               // Create the kernel type manager.
  -            // Create a context object container the logging manager and the 
  +            // Create a context object container the logging manager and the
               // categories to be applied relative to the manager's path, include
               // the extension directives and classpath descriptor.
               //
   
  -            ExtensionsDescriptor extensions = 
  +            ExtensionsDescriptor extensions =
                 m_creator.createExtensionsDescriptor( m_config.getChild("extensions") );
  -            ClasspathDescriptor classpath = 
  +            ClasspathDescriptor classpath =
                 m_creator.createClasspathDescriptor( m_config.getChild("classpath") );
   
               m_manager = new KernelManager( m_base );
  @@ -374,7 +409,7 @@
                       Class clazz = m_manager.loadClass( lifestyleClassname );
                       lifestyles = (LifestyleManager) clazz.newInstance();
                       if( lifestyles instanceof LogEnabled )
  -                      ((LogEnabled)lifestyles).enableLogging( 
  +                      ((LogEnabled)lifestyles).enableLogging(
                           getLogger().getChildLogger("lifestyles") );
                       if( lifestyles instanceof Configurable )
                         ((Configurable)lifestyles).configure( lifestyleConfig );
  @@ -388,11 +423,11 @@
                   }
               }
   
  -            // 
  +            //
               // setup the root container
               //
   
  -            ContainerFactory factory = 
  +            ContainerFactory factory =
                 new ContainerFactory( m_manager, getLoggingManager(), lifestyles );
               factory.enableLogging( m_logger );
   
  @@ -513,6 +548,8 @@
               ((Disposable)m_container).dispose();
           }
           m_manager.dispose();
  +
  +        m_threadManager.dispose();
       }
   
       //=======================================================================
  @@ -543,7 +580,7 @@
             throw new IllegalStateException("not initialized");
   
           getLogger().debug("verify");
  -        
  +
           Profile[] profiles = m_manager.getStartupGraph( false );
           MetaDataVerifier mdv = new MetaDataVerifier();
           for( int i=0; i<profiles.length; i++ )
  
  
  
  1.5       +49 -32    jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/resource/DefaultLifestyleManager.java
  
  Index: DefaultLifestyleManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/resource/DefaultLifestyleManager.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DefaultLifestyleManager.java	15 Aug 2002 04:14:49 -0000	1.4
  +++ DefaultLifestyleManager.java	16 Aug 2002 03:09:24 -0000	1.5
  @@ -10,6 +10,8 @@
   package org.apache.excalibur.merlin.resource;
   
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
  +import org.apache.avalon.framework.context.Contextualizable;
  +import org.apache.avalon.framework.context.ContextException;
   import org.apache.avalon.framework.context.Context;
   import org.apache.avalon.framework.configuration.Configurable;
   import org.apache.avalon.framework.configuration.Configuration;
  @@ -17,52 +19,58 @@
   import org.apache.avalon.framework.activity.Initializable;
   import org.apache.excalibur.merlin.assembly.ContainerManager;
   import org.apache.excalibur.merlin.model.Profile;
  +import org.apache.excalibur.mpool.PoolManager;
   
   /**
  - * Utility class that handles the establishment of an appropriate lifestyle 
  - * handler based on a supplied profile. 
  + * Utility class that handles the establishment of an appropriate lifestyle
  + * handler based on a supplied profile.
    *
    * @author <a href="mailto:mcconnell@osm.net">Stephen McConnell</a>
    */
  -public class DefaultLifestyleManager extends AbstractLogEnabled 
  -implements LifestyleManager, Configurable, Initializable
  +public class DefaultLifestyleManager extends AbstractLogEnabled
  +implements LifestyleManager, Configurable, Contextualizable, Initializable
   {
  -
        private Configuration m_config;
  +     private PoolManager m_poolManager;
   
        public void configure( Configuration config )
        {
            m_config = config;
        }
   
  +     public void contextualize( Context context ) throws ContextException
  +     {
  +         m_poolManager = (PoolManager) context.get("pool-manager");
  +     }
  +
        public void initialize() throws Exception
        {
        }
   
       /**
  -     * <p>Returns a lifestyle handler implementation based on a supplied 
  +     * <p>Returns a lifestyle handler implementation based on a supplied
        * profile.  The implementation recognizes the following lifestyle
  -     * policy declarations supplied as values against the component 
  +     * policy declarations supplied as values against the component
        * attribute <strong>avalon:lifestyle</strong>:</p>
        *
        * <table>
        *  <tr><td><p>policy</p></td><td><p>description</p></td></tr>
        *  <tr><td><p>singleton</p></td><td>
  -     *    <p>single service instance is sharable across mutiple 
  +     *    <p>single service instance is sharable across mutiple
        *       instances operating in different threads</p></td></tr>
        *  <tr><td><p>thread</p></td><td>
  -     *    <p>a new service instance is establied under the first request 
  -     *       within the scope of a particular thread.  The instance is 
  -     *       subsequently shared across mutiple instances within the 
  +     *    <p>a new service instance is establied under the first request
  +     *       within the scope of a particular thread.  The instance is
  +     *       subsequently shared across mutiple instances within the
        *       scope of a particular thread</p></td></tr>
        *  <tr><td><p>pooled</p></td><td>
  -     *    <p>service instaces are maintainer in a pool and recycled 
  +     *    <p>service instaces are maintainer in a pool and recycled
        *       by the lifestyle handler</p></td></tr>
        *  <tr><td><p>transient</p></td><td>
        *    <p>new instances are created per request</p></td></tr>
        *  <tr><td><p>custom</p></td><td>
        *    <p>the handler policy is defined by a custom implementation
  -     *       class declared under the attribute key 
  +     *       class declared under the attribute key
        *       <strong>avalon:lifestyle.class</strong></p></td></tr>
        * </table>
        *
  @@ -75,25 +83,25 @@
        * @return a lifecycle handler supporting the requested policy
        * @exception Exception if an error occurs during handler establishment
        */
  -     public LifestyleHandler getHandler( 
  -                            ContainerManager manager, 
  +     public LifestyleHandler getHandler(
  +                            ContainerManager manager,
                               DeploymentHelper deployment,
  -                            LifecycleHelper helper, 
  -                            Profile profile, 
  -                            Context context ) 
  +                            LifecycleHelper helper,
  +                            Profile profile,
  +                            Context context )
        throws Exception
        {
   
  -        final String policy = 
  +        final String policy =
             profile.getType().getInfo().getAttribute("avalon:lifestyle", "singleton" );
   
  -        if( policy.equalsIgnoreCase( "singleton" ) ) 
  +        if( policy.equalsIgnoreCase( "singleton" ) )
           {
               //
               // create a thread safe lifestyle handler
               //
   
  -            SingletonLifestyleHandler handler = 
  +            SingletonLifestyleHandler handler =
                 new SingletonLifestyleHandler( manager, deployment, helper, profile, context );
               handler.enableLogging( getLogger() );
               return handler;
  @@ -104,33 +112,42 @@
               // create a transient lifestyle handler
               //
   
  -            TransientLifestyleHandler handler = 
  +            TransientLifestyleHandler handler =
                 new TransientLifestyleHandler( manager, deployment, helper, profile, context );
               handler.enableLogging( getLogger() );
               return handler;
           }
  -        else if( policy.equalsIgnoreCase( "thread" ) ) 
  +        else if( policy.equalsIgnoreCase( "thread" ) )
           {
               //
  -            // per-thread lifestyle handler not implemented
  +            // create a per-thread lifestyle handler
               //
   
  -            ThreadLocalLifestyleHandler handler = 
  +            ThreadLocalLifestyleHandler handler =
                 new ThreadLocalLifestyleHandler( manager, deployment, helper, profile, context );
               handler.enableLogging( getLogger() );
               return handler;
           }
  -        else if( policy.equalsIgnoreCase( "pooled" ) ) 
  +        else if( policy.equalsIgnoreCase( "pooled" ) )
           {
               //
  -            // pooled lifestyle handler not implemented
  +            // create a pooled lifestyle handler
               //
   
  -            final String error = 
  -              "Pooled lifestyle policy in profile: '" 
  -              + manager.getPath() + "/" + profile.getName()
  -              + "' unavailable.";
  -            throw new UnsupportedOperationException( error );
  +            try
  +            {
  +                PooledLifestyleHandler handler =
  +                  new PooledLifestyleHandler( manager, deployment, helper, profile, context, m_poolManager );
  +                handler.enableLogging( getLogger() );
  +                return handler;
  +            }
  +            catch (Exception e)
  +            {
  +                final String error =
  +                  "Unable to handle the 'pooled' lifestyle policy due to an error\n"
  +                  + e.getMessage();
  +                throw new IllegalArgumentException( error );
  +            }
           }
           else
           {
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/resource/PooledLifestyleHandler.java
  
  Index: PooledLifestyleHandler.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.TXT file.
   *
   * Original contribution by OSM SARL, http://www.osm.net
   */
  package org.apache.excalibur.merlin.resource;
  
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.context.DefaultContext;
  import org.apache.avalon.framework.context.Context;
  import org.apache.excalibur.merlin.assembly.ContainerManager;
  import org.apache.excalibur.merlin.model.Profile;
  import org.apache.excalibur.merlin.model.Resource;
  import org.apache.excalibur.meta.info.PhaseDescriptor;
  import org.apache.excalibur.meta.info.ExtensionDescriptor;
  import org.apache.excalibur.mpool.PoolManager;
  import org.apache.excalibur.mpool.Pool;
  import org.apache.excalibur.mpool.ObjectFactory;
  
  
  /**
   * Lifestyle implementation that provides suppport for the pooled
   * policy.  Request for an instance will be served from a pool of
   * components.
   *
   * NOTE: This is untested.
   *
   * @author <a href="mailto:mcconnell@osm.net">Stephen McConnell</a>
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   */
  public class PooledLifestyleHandler extends AbstractLifestyleHandler implements ObjectFactory
  {
       private Profile m_profile;
       private ContainerManager m_manager;
  
       private Pool m_pool;
  
      /**
       * Creation of a new singleton lifecycle manager.
       * @param manager the type manager
       * @param provider the resource provider
       * @param helper the lifecycle helper
       * @param profile the profile defining the object type
       * @param context the establishment context
       */
       public PooledLifestyleHandler(
                             final ContainerManager manager,
                             final DeploymentHelper deployment,
                             final LifecycleHelper helper,
                             final Profile profile,
                             final Context context,
                             final PoolManager poolManager)
           throws Exception
       {
           super( manager, deployment, helper, profile, context );
           m_profile = profile;
           m_manager = manager;
           // get a pool for our component with 5 initial entries
           m_pool = poolManager.getManagedPool( this, 5 );
       }
  
      /**
       * Returns an instance of the object type supported by the
       * manager to the client.
       *
       * @return an instance of the type defined by the profile
       */
       public Object get() throws Exception
       {
           if( m_disposed )
             throw new IllegalStateException("disposed");
  
           getLogger().debug("get");
  
           Object object = m_pool.acquire();
           super.processAccessStage( object );
  
           return object;
  
       }
  
      /**
       * Invoked by a client to return an instance of the object type previously
       * supported by the manager.  The singleton manager does nothing as the
       * object may be used across an arbitary number of clients.
       *
       * @param object the object to return
       */
       public void put( Object object ) throws Exception
       {
           if( m_disposed )
             throw new IllegalStateException("disposed");
  
           getLogger().debug("put");
           if( object == null )
             return;
  
           if( object.getClass().equals( getCreatedClass() ) )
           {
               super.processReleaseStage( object );
               m_pool.release( object );
           }
           else
           {
               final String warning =
                 "Illegal attempt to release an object that was not provided by this handler.";
               getLogger().warn( warning );
           }
       }
  
       public Object newInstance() throws Exception
       {
           return createInstance();
       }
  
       public void dispose( Object object ) throws Exception
       {
           handleShutdown( object );
       }
  
       public Class getCreatedClass()
       {
           return getImplementationClass();
       }
  
      /**
       * Request for disposal of the manager.  This operation is normally invoked
       * by the client that initialy instantiated the manager.  The implementation
       * handles the disposal of the singleton resoruce and release of associated
       * references.
       */
       public void dispose()
       {
           if ( m_pool instanceof Disposable )
           {
               ( (Disposable) m_pool ).dispose();
           }
  
           m_pool = null;
           m_profile = null;
           m_manager = null;
  
           super.dispose();
       }
  }
  
  
  

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