All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.enterprise.web.connector.grizzly.KeepAlivePipeline Maven / Gradle / Ivy

The newest version!
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.enterprise.web.connector.grizzly;

import java.nio.channels.SelectionKey;
import java.util.concurrent.ConcurrentHashMap;


/**
 * Keep Alive subsystems. This class will cancel SelectionKey
 * based on the maxKeepAliveRequests.
 *
 * @author Jeanfrancois Arcand
 */
public class KeepAlivePipeline{
    
    
    public final static int KEEP_ALIVE_RULE = 0;
    
    /**
     * The maximum number of Thread
     */
    private int maxThreads = 1;
   
    
    /**
     * The Thread Priority
     */
    private int priority = Thread.NORM_PRIORITY;
    
    
    /**
     * The port used.
     */
    private int port = 8080;
        

    /**
     * The name of this Pipeline
     */
    private String name;
    
    
    /**
     * Has the pipeline already started
     */
    private boolean isStarted = false; 
    
    
    /*
     * Number of seconds before idle accepted connections expire.
     * Default is 30 seconds as per domain.xml DTD.
     */
    private int firstReadTimeout = Constants.DEFAULT_TIMEOUT; 
    
    /*
     * Number of seconds before idle keep-alive connections expire.
     * Default is 30 seconds as per domain.xml DTD.
     */
    private int keepAliveTimeoutInSeconds = Constants.DEFAULT_TIMEOUT;
    
    
    /**
     * Placeholder for keep-alive count monitoring.
     */
    protected ConcurrentHashMap keepAliveCounts;
    
    
    /**
     * Maximum number of requests in a single transaction.
     */
    protected int maxKeepAliveRequests = -1;
    
    
    /**
     * The PipelineStatistic objects used when gathering statistics.
     */
    protected PipelineStatistic pipelineStat;     
      
    
    /**
     * The stats object used to gather statistics.
     */
    private KeepAliveStats keepAliveStats;


    // ----------------------------------------------- Constructor ----------//
    
    /**
     * Default constructor.
     */
    public KeepAlivePipeline(){
        initPipeline();
    }
   
    // ------------------------------------------------ Lifecycle ------------/
    
    /**
     * Init the Pipeline by initializing the required
     * WorkerThread. 
     */
    public void initPipeline(){
        if (isStarted){
            return;
        }
        isStarted = true;
        keepAliveCounts = new ConcurrentHashMap();     
    }

    
    /**
     * Start the Pipeline and all associated 
     * WorkerThread
     */
    public void startPipeline(){
        if (isStarted){
            return;
        }
    }
    

    /**
     * Stop the Pipeline and all associated
     * WorkerThread
     */
    public void stopPipeline(){
        if (!isStarted){
            return;
        }
        isStarted = false;
        keepAliveCounts.clear();
    }
    
    // ---------------------------------------------------- Queue ------------//
  
    
    /**
     * Add an object to this pipeline
     */
    public void addTask(Task task){
        throw new UnsupportedOperationException();
    }


    /**
     * Return a SelectionKey object available in the pipeline.
     * All Threads will synchronize on that method
     * @Return null This pipeline doesn't supports this method.
     */
    public Task getTask() {
        return null;
    }
    

    /**
     * Returns the number of tasks in this Pipeline.
     *
     * @return Number of tasks in this Pipeline.
     */
    public int size() {
        return 0;
    }

    
    // --------------------------------------------------Properties ----------//

     /**
     * Return the number of waiting threads.
     */
    public int getWaitingThread(){
        return 0;
    }
    
    
    /** 
     * Set the number of threads used by this pipeline.
     */
    public void setMaxThreads(int maxThreads){
        this.maxThreads = maxThreads;
    }    
    
    
    /** 
     * Return the number of threads used by this pipeline.
     */
    public int getMaxThreads(){
        return maxThreads;
    }
    
    
    /**
     * Return the current number of active threads.
     */
    public int getCurrentThreadCount() {
        return 1;
    }
    
    
    /**
     * Return the current number of active threads.
     */
    public int getCurrentThreadsBusy() {
        return 1;
    }
    
    
    /**
     * Return the maximum spare thread.
     */
    public int getMaxSpareThreads() {
        return 0;
    }     

    
    /**
     * Set the thread priority of the Pipeline
     */
    public void setPriority(int priority){
        this.priority = priority;
    }
    
    
    /**
     * Set the name of this Pipeline
     */
    public void setName(String name){
        this.name = name;
    }
    
    
    /**
     * Return the name of this Pipeline
     * @return the name of this Pipeline
     */
    public String getName(){
        return name+port;
    }    

    
    /**
     * Set the port used by this Pipeline
     * @param port the port used by this Pipeline
     */
    public void setPort(int port){
        this.port = port;
    }
    
    
    /**
     * Set the minimum thread this Pipeline will creates
     * when initializing.
     * @param minThreads the minimum number of threads.
     */
    public void setMinThreads(int minThreads){
        throw new UnsupportedOperationException();
    }
    
    
    @Override
    public String toString(){
       return "name: " + name + " maxThreads: " + maxThreads ;        
    }

    
    /**
     * Set the maximum pending connection this Pipeline
     * can handle.
     */
    public void setQueueSizeInBytes(int maxQueueSizeInBytes){
        throw new UnsupportedOperationException(); 
    }
    
    
    public void setThreadsIncrement(int threadsIncrement){
       throw new UnsupportedOperationException();
    }
    
    
    public void setThreadsTimeout(int threadsTimeout){
        this.firstReadTimeout = threadsTimeout;
    }


    /**
     * Return the minimum spare thread.
     */
    public int getMinSpareThreads() {
        throw new UnsupportedOperationException();
    }


    /**
     * Set the minimum space thread this Pipeline can handle.
     */
    public void setMinSpareThreads(int minSpareThreads) {
        throw new UnsupportedOperationException();
    }

    
    // ------------------------------------------------ maxKeepAliveRequests --/
    
    /**
     * Monitor keep-alive request count for the given connection.
     * @return true if the request can be processed, false if the maximun
     *              number of requests has been reached.
     */
    public boolean trap(SelectionKey key){
        if ( maxKeepAliveRequests == -1) return true;
        
        Integer count = keepAliveCounts.get(key);
        if ( count == null ){
            count = 0;
            if (keepAliveStats != null) {
                keepAliveStats.incrementCountConnections();
            }
        }
        
        if ((count+1) > maxKeepAliveRequests){
            if (keepAliveStats != null) {
                keepAliveStats.incrementCountRefusals();
            }
            return false;
        }

        count++;
        keepAliveCounts.put(key, count);
        if (keepAliveStats != null) {
            keepAliveStats.incrementCountHits();
        }

        return true;
    }
    
    
    /**
     * Stop monitoring keep-alive request count for the given connection.
     */
    public void untrap(SelectionKey key){
        if ( maxKeepAliveRequests == -1) return;
        
        if (keepAliveCounts.remove(key) != null
                && keepAliveStats != null) {
            keepAliveStats.decrementCountConnections();
        }
    }
    
    
    /**
     * Is the SelectionKey already added to the keep-alive mechanism.
     */
    public boolean isKeepAlive(SelectionKey key){
        return (keepAliveCounts.get(key) != null);
    }
    
    
    /**
     * Return the maximum number of keep-alive requests per connection.
     */
    public int getMaxKeepAliveRequests() {
        return maxKeepAliveRequests;
    }
    
    
    /** 
     * Set the maximum number of Keep-Alive requests that we will 
     * honor per connection. A value < 0 will disabled the keep-alive mechanism.
     */
    public void setMaxKeepAliveRequests(int maxKeepAliveRequests) {
        this.maxKeepAliveRequests = maxKeepAliveRequests;
    }
    
        
    /**
     * Sets the number of seconds before a keep-alive connection that has
     * been idle times out and is closed.
     *
     * @param keepAliveTimeout Keep-alive timeout in number of seconds
     */
    public void setKeepAliveTimeoutInSeconds(int keepAliveTimeout){
        this.keepAliveTimeoutInSeconds = keepAliveTimeout;
    }
                                                                                
                                                                                
    /**
     * Gets the number of seconds before a keep-alive connection that has
     * been idle times out and is closed.
     *
     * @return Keep-alive timeout in number of seconds
     */
    public int getKeepAliveTimeoutInSeconds(){
        return keepAliveTimeoutInSeconds;
    }
    

    /**
     * Return true if we need to close the connection just after 
     * the first request.
     */
    public boolean dropConnection(){
        return (keepAliveTimeoutInSeconds == 0 
                    || firstReadTimeout == 0 || maxKeepAliveRequests == 0);
    }
       
    /**
     * Return true if we need to close the connection after
     * processing current request.
     */
    public boolean dropConnection(final SelectionKey selectionKey) {
        Integer count;
        
        return (keepAliveTimeoutInSeconds == 0
                    || firstReadTimeout == 0 || maxKeepAliveRequests == 0 ||
                    (maxKeepAliveRequests > 0 &&
                    (count = keepAliveCounts.get(selectionKey)) != null &&
                    count >= maxKeepAliveRequests));
    }
    
    
    /**
     * Set the PipelineStatistic object used
     * to gather statistic;
     */
    public void setPipelineStatistic(PipelineStatistic pipelineStatistic){
        this.pipelineStat = pipelineStatistic;
    }
    
    
    /**
     * Return the PipelineStatistic object used
     * to gather statistic;
     */
    public PipelineStatistic getPipelineStatistic(){
        return pipelineStat;
    }
    

    /**
     * Sets the given KeepAliveStats, which is responsible for storing
     * keep-alive statistics.
     *
     * @param keepAliveStats The KeepAliveStats object responsible for 
     * storing keep-alive statistics
     */
    void setKeepAliveStats(KeepAliveStats keepAliveStats) {
        this.keepAliveStats = keepAliveStats;
    }

    
    /**
     * Interrupt the Thread using it thread id
     */
    public boolean interruptThread(long threadId){
        return false;
    }
}