001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    package org.apache.geronimo.connector.work.pool;
019    
020    import java.util.concurrent.LinkedBlockingQueue;
021    import java.util.concurrent.ThreadPoolExecutor;
022    import java.util.concurrent.TimeUnit;
023    
024    import org.slf4j.Logger;
025    import org.slf4j.LoggerFactory;
026    
027    
028    /**
029     * Based class for WorkExecutorPool. Sub-classes define the synchronization
030     * policy (should the call block until the end of the work; or when it starts
031     * et cetera).
032     *
033     * @version $Rev: 723385 $ $Date: 2008-12-04 12:55:02 -0500 (Thu, 04 Dec 2008) $
034     */
035    public class WorkExecutorPoolImpl implements WorkExecutorPool {
036    
037        /**
038         * A timed out pooled executor.
039         */
040        private ThreadPoolExecutor pooledExecutor;
041        private static Logger log = LoggerFactory.getLogger(WorkExecutorPoolImpl.class);
042    
043        /**
044         * Creates a pool with the specified minimum and maximum sizes. The Channel
045         * used to enqueue the submitted Work instances is queueless synchronous
046         * one.
047         *
048         * @param maxSize Maximum size of the work executor pool.
049         */
050        public WorkExecutorPoolImpl(int maxSize) {
051            pooledExecutor = new ThreadPoolExecutor(1, maxSize, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
052            /*
053            FIXME: How to do this with concurrent.util ?
054            pooledExecutor.waitWhenBlocked();
055            */
056        }
057        
058        /**
059         * Execute the specified Work.
060         *
061         * @param work Work to be executed.
062         */
063        public void execute(Runnable work) {
064            if(pooledExecutor.getPoolSize() == pooledExecutor.getMaximumPoolSize()) {
065                log.warn("Maximum Pool size has been exceeded.  Current Pool Size = "+pooledExecutor.getMaximumPoolSize());
066            }
067    
068            pooledExecutor.execute(work);
069        }
070    
071        /**
072         * Gets the size of this pool.
073         */
074        public int getPoolSize() {
075            return pooledExecutor.getPoolSize();
076        }
077    
078        /**
079         * Gets the maximum size of this pool.
080         */
081        public int getMaximumPoolSize() {
082            return pooledExecutor.getMaximumPoolSize();
083        }
084    
085        /**
086         * Sets the maximum size of this pool.
087         * @param maxSize New maximum size of this pool.
088         */
089        public void setMaximumPoolSize(int maxSize) {
090            pooledExecutor.setMaximumPoolSize(maxSize);
091        }
092    
093        public WorkExecutorPool start() {
094            throw new IllegalStateException("This pooled executor is already started");
095        }
096    
097        /**
098         * Stops this pool. Prior to stop this pool, all the enqueued Work instances
099         * are processed. This is an orderly shutdown.
100         */
101        public WorkExecutorPool stop() {
102            int maxSize = getMaximumPoolSize();
103            pooledExecutor.shutdown();
104            return new NullWorkExecutorPool(maxSize);
105        }
106    
107    }