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;
}
}