368240: Added concept of join to AggregateLifeCycle. Used by HttpClient and AbstractConnector

This commit is contained in:
Greg Wilkins 2012-01-11 00:09:34 +11:00
parent 31bd00ab79
commit 968a2ac95b
15 changed files with 863 additions and 327 deletions

View File

@ -29,7 +29,9 @@ import org.eclipse.jetty.client.security.Authentication;
import org.eclipse.jetty.client.security.RealmResolver;
import org.eclipse.jetty.client.security.SecurityListener;
import org.eclipse.jetty.http.HttpBuffers;
import org.eclipse.jetty.http.HttpBuffersImpl;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.Buffers.Type;
import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.AttributesMap;
@ -66,7 +68,7 @@ import org.eclipse.jetty.util.thread.Timeout;
* @see HttpExchange
* @see HttpDestination
*/
public class HttpClient extends HttpBuffers implements Attributes, Dumpable
public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attributes, Dumpable
{
public static final int CONNECTOR_SOCKET = 0;
public static final int CONNECTOR_SELECT_CHANNEL = 2;
@ -91,43 +93,46 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
private int _maxRedirects = 20;
private LinkedList<String> _registeredListeners;
private SslContextFactory _sslContextFactory;
private final SslContextFactory _sslContextFactory;
private RealmResolver _realmResolver;
private AttributesMap _attributes=new AttributesMap();
private final HttpBuffersImpl _buffers= new HttpBuffersImpl();
/* ------------------------------------------------------------------------------- */
private void setBufferTypes()
{
if (_connectorType==CONNECTOR_SOCKET)
{
setRequestBufferType(Type.BYTE_ARRAY);
setRequestHeaderType(Type.BYTE_ARRAY);
setResponseBufferType(Type.BYTE_ARRAY);
setResponseHeaderType(Type.BYTE_ARRAY);
_buffers.setRequestBufferType(Type.BYTE_ARRAY);
_buffers.setRequestHeaderType(Type.BYTE_ARRAY);
_buffers.setResponseBufferType(Type.BYTE_ARRAY);
_buffers.setResponseHeaderType(Type.BYTE_ARRAY);
}
else
{
setRequestBufferType(Type.DIRECT);
setRequestHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT);
setResponseBufferType(Type.DIRECT);
setResponseHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT);
_buffers.setRequestBufferType(Type.DIRECT);
_buffers.setRequestHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT);
_buffers.setResponseBufferType(Type.DIRECT);
_buffers.setResponseHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT);
}
}
/* ------------------------------------------------------------------------------- */
public HttpClient()
{
this(new SslContextFactory());
setBufferTypes();
}
/* ------------------------------------------------------------------------------- */
public HttpClient(SslContextFactory sslContextFactory)
{
_sslContextFactory = sslContextFactory;
addBean(_sslContextFactory);
addBean(_buffers);
setBufferTypes();
}
@ -149,25 +154,6 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
_connectBlocking = connectBlocking;
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.util.component.Dumpable#dump()
*/
public String dump()
{
return AggregateLifeCycle.dump(this);
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.util.component.Dumpable#dump(java.lang.Appendable, java.lang.String)
*/
public void dump(Appendable out, String indent) throws IOException
{
out.append(String.valueOf(this)).append("\n");
AggregateLifeCycle.dump(out,indent,Arrays.asList(_threadPool,_connector),_destinations.values());
}
/* ------------------------------------------------------------------------------- */
public void send(HttpExchange exchange) throws IOException
{
@ -190,6 +176,7 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
pool.setDaemon(true);
pool.setName("HttpClient");
_threadPool = pool;
addBean(_threadPool,true);
}
return _threadPool;
@ -201,7 +188,9 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
*/
public void setThreadPool(ThreadPool threadPool)
{
removeBean(_threadPool);
_threadPool = threadPool;
addBean(_threadPool);
}
@ -338,6 +327,7 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
}
/* ------------------------------------------------------------ */
/**
* Registers a listener that can listen to the stream of execution between the client and the
* server and influence events. Sequential calls to the method wrapper sequentially wrap the preceding
@ -422,7 +412,6 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
protected void doStart() throws Exception
{
setBufferTypes();
super.doStart();
_timeoutQ.setDuration(_timeout);
_timeoutQ.setNow();
@ -432,24 +421,12 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
if (_threadPool == null)
getThreadPool();
if (_threadPool instanceof LifeCycle)
{
((LifeCycle)_threadPool).start();
}
_sslContextFactory.start();
if (_connectorType == CONNECTOR_SELECT_CHANNEL)
{
_connector = new SelectConnector(this);
}
else
{
_connector = new SocketConnector(this);
}
_connector.start();
_connector=(_connectorType == CONNECTOR_SELECT_CHANNEL)?new SelectConnector(this):new SocketConnector(this);
addBean(_connector,true);
super.doStart();
_threadPool.dispatch(new Runnable()
{
public void run()
@ -480,14 +457,6 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
@Override
protected void doStop() throws Exception
{
_connector.stop();
_connector = null;
_sslContextFactory.stop();
if (_threadPool instanceof LifeCycle)
{
((LifeCycle)_threadPool).stop();
}
for (HttpDestination destination : _destinations.values())
{
destination.close();
@ -496,6 +465,8 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
_timeoutQ.cancelAll();
_idleTimeoutQ.cancelAll();
super.doStop();
_connector = null;
removeBean(_connector);
}
/* ------------------------------------------------------------ */
@ -667,6 +638,98 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
_maxRedirects = redirects;
}
public int getRequestBufferSize()
{
return _buffers.getRequestBufferSize();
}
public void setRequestBufferSize(int requestBufferSize)
{
_buffers.setRequestBufferSize(requestBufferSize);
}
public int getRequestHeaderSize()
{
return _buffers.getRequestHeaderSize();
}
public void setRequestHeaderSize(int requestHeaderSize)
{
_buffers.setRequestHeaderSize(requestHeaderSize);
}
public int getResponseBufferSize()
{
return _buffers.getResponseBufferSize();
}
public void setResponseBufferSize(int responseBufferSize)
{
_buffers.setResponseBufferSize(responseBufferSize);
}
public int getResponseHeaderSize()
{
return _buffers.getResponseHeaderSize();
}
public void setResponseHeaderSize(int responseHeaderSize)
{
_buffers.setResponseHeaderSize(responseHeaderSize);
}
public Type getRequestBufferType()
{
return _buffers.getRequestBufferType();
}
public Type getRequestHeaderType()
{
return _buffers.getRequestHeaderType();
}
public Type getResponseBufferType()
{
return _buffers.getResponseBufferType();
}
public Type getResponseHeaderType()
{
return _buffers.getResponseHeaderType();
}
public void setRequestBuffers(Buffers requestBuffers)
{
_buffers.setRequestBuffers(requestBuffers);
}
public void setResponseBuffers(Buffers responseBuffers)
{
_buffers.setResponseBuffers(responseBuffers);
}
public Buffers getRequestBuffers()
{
return _buffers.getRequestBuffers();
}
public Buffers getResponseBuffers()
{
return _buffers.getResponseBuffers();
}
public void setMaxBuffers(int maxBuffers)
{
_buffers.setMaxBuffers(maxBuffers);
}
public int getMaxBuffers()
{
return _buffers.getMaxBuffers();
}
/* ------------------------------------------------------------ */
@Deprecated
public String getTrustStoreLocation()

View File

@ -97,9 +97,9 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
if (_httpClient.isConnectBlocking())
{
channel.socket().connect(address.toSocketAddress(), _httpClient.getConnectTimeout());
channel.configureBlocking(false);
_selectorManager.register( channel, destination );
channel.socket().connect(address.toSocketAddress(), _httpClient.getConnectTimeout());
channel.configureBlocking(false);
_selectorManager.register( channel, destination );
}
else
{

View File

@ -19,211 +19,85 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle;
/* ------------------------------------------------------------ */
/** Abstract Buffer pool.
* simple unbounded pool of buffers for header, request and response sizes.
*
*/
public class HttpBuffers extends AbstractLifeCycle
public interface HttpBuffers
{
private int _requestBufferSize=16*1024;
private int _requestHeaderSize=6*1024;
private int _responseBufferSize=32*1024;
private int _responseHeaderSize=6*1024;
private int _maxBuffers=1024;
private Buffers.Type _requestBufferType=Buffers.Type.BYTE_ARRAY;
private Buffers.Type _requestHeaderType=Buffers.Type.BYTE_ARRAY;
private Buffers.Type _responseBufferType=Buffers.Type.BYTE_ARRAY;
private Buffers.Type _responseHeaderType=Buffers.Type.BYTE_ARRAY;
private Buffers _requestBuffers;
private Buffers _responseBuffers;
public HttpBuffers()
{
super();
}
/**
* @return the requestBufferSize
*/
public int getRequestBufferSize()
{
return _requestBufferSize;
}
public int getRequestBufferSize();
/**
* @param requestBufferSize the requestBufferSize to set
*/
public void setRequestBufferSize(int requestBufferSize)
{
_requestBufferSize = requestBufferSize;
}
public void setRequestBufferSize(int requestBufferSize);
/**
* @return the requestHeaderSize
*/
public int getRequestHeaderSize()
{
return _requestHeaderSize;
}
public int getRequestHeaderSize();
/**
* @param requestHeaderSize the requestHeaderSize to set
*/
public void setRequestHeaderSize(int requestHeaderSize)
{
_requestHeaderSize = requestHeaderSize;
}
public void setRequestHeaderSize(int requestHeaderSize);
/**
* @return the responseBufferSize
*/
public int getResponseBufferSize()
{
return _responseBufferSize;
}
public int getResponseBufferSize();
/**
* @param responseBufferSize the responseBufferSize to set
*/
public void setResponseBufferSize(int responseBufferSize)
{
_responseBufferSize = responseBufferSize;
}
public void setResponseBufferSize(int responseBufferSize);
/**
* @return the responseHeaderSize
*/
public int getResponseHeaderSize()
{
return _responseHeaderSize;
}
public int getResponseHeaderSize();
/**
* @param responseHeaderSize the responseHeaderSize to set
*/
public void setResponseHeaderSize(int responseHeaderSize)
{
_responseHeaderSize = responseHeaderSize;
}
public void setResponseHeaderSize(int responseHeaderSize);
/**
* @return the requestBufferType
*/
public Buffers.Type getRequestBufferType()
{
return _requestBufferType;
}
/**
* @param requestBufferType the requestBufferType to set
*/
protected void setRequestBufferType(Buffers.Type requestBufferType)
{
_requestBufferType = requestBufferType;
}
public Buffers.Type getRequestBufferType();
/**
* @return the requestHeaderType
*/
public Buffers.Type getRequestHeaderType()
{
return _requestHeaderType;
}
/**
* @param requestHeaderType the requestHeaderType to set
*/
protected void setRequestHeaderType(Buffers.Type requestHeaderType)
{
_requestHeaderType = requestHeaderType;
}
public Buffers.Type getRequestHeaderType();
/**
* @return the responseBufferType
*/
public Buffers.Type getResponseBufferType()
{
return _responseBufferType;
}
/**
* @param responseBufferType the responseBufferType to set
*/
protected void setResponseBufferType(Buffers.Type responseBufferType)
{
_responseBufferType = responseBufferType;
}
public Buffers.Type getResponseBufferType();
/**
* @return the responseHeaderType
*/
public Buffers.Type getResponseHeaderType()
{
return _responseHeaderType;
}
/**
* @param responseHeaderType the responseHeaderType to set
*/
protected void setResponseHeaderType(Buffers.Type responseHeaderType)
{
_responseHeaderType = responseHeaderType;
}
public Buffers.Type getResponseHeaderType();
/**
* @param requestBuffers the requestBuffers to set
*/
public void setRequestBuffers(Buffers requestBuffers)
{
_requestBuffers = requestBuffers;
}
public void setRequestBuffers(Buffers requestBuffers);
/**
* @param responseBuffers the responseBuffers to set
*/
public void setResponseBuffers(Buffers responseBuffers)
{
_responseBuffers = responseBuffers;
}
public void setResponseBuffers(Buffers responseBuffers);
@Override
protected void doStart()
throws Exception
{
_requestBuffers=BuffersFactory.newBuffers(_requestHeaderType,_requestHeaderSize,_requestBufferType,_requestBufferSize,_requestBufferType,getMaxBuffers());
_responseBuffers=BuffersFactory.newBuffers(_responseHeaderType,_responseHeaderSize,_responseBufferType,_responseBufferSize,_responseBufferType,getMaxBuffers());
super.doStart();
}
@Override
protected void doStop()
throws Exception
{
_requestBuffers=null;
_responseBuffers=null;
}
public Buffers getRequestBuffers();
public Buffers getRequestBuffers()
{
return _requestBuffers;
}
public Buffers getResponseBuffers();
public Buffers getResponseBuffers()
{
return _responseBuffers;
}
public void setMaxBuffers(int maxBuffers);
public void setMaxBuffers(int maxBuffers)
{
_maxBuffers = maxBuffers;
}
public int getMaxBuffers()
{
return _maxBuffers;
}
public int getMaxBuffers();
}

View File

@ -0,0 +1,233 @@
// ========================================================================
// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.http;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.BuffersFactory;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
/* ------------------------------------------------------------ */
/** Abstract Buffer pool.
* simple unbounded pool of buffers for header, request and response sizes.
*
*/
public class HttpBuffersImpl extends AbstractLifeCycle implements HttpBuffers
{
private int _requestBufferSize=16*1024;
private int _requestHeaderSize=6*1024;
private int _responseBufferSize=32*1024;
private int _responseHeaderSize=6*1024;
private int _maxBuffers=1024;
private Buffers.Type _requestBufferType=Buffers.Type.BYTE_ARRAY;
private Buffers.Type _requestHeaderType=Buffers.Type.BYTE_ARRAY;
private Buffers.Type _responseBufferType=Buffers.Type.BYTE_ARRAY;
private Buffers.Type _responseHeaderType=Buffers.Type.BYTE_ARRAY;
private Buffers _requestBuffers;
private Buffers _responseBuffers;
public HttpBuffersImpl()
{
super();
}
/**
* @return the requestBufferSize
*/
public int getRequestBufferSize()
{
return _requestBufferSize;
}
/**
* @param requestBufferSize the requestBufferSize to set
*/
public void setRequestBufferSize(int requestBufferSize)
{
_requestBufferSize = requestBufferSize;
}
/**
* @return the requestHeaderSize
*/
public int getRequestHeaderSize()
{
return _requestHeaderSize;
}
/**
* @param requestHeaderSize the requestHeaderSize to set
*/
public void setRequestHeaderSize(int requestHeaderSize)
{
_requestHeaderSize = requestHeaderSize;
}
/**
* @return the responseBufferSize
*/
public int getResponseBufferSize()
{
return _responseBufferSize;
}
/**
* @param responseBufferSize the responseBufferSize to set
*/
public void setResponseBufferSize(int responseBufferSize)
{
_responseBufferSize = responseBufferSize;
}
/**
* @return the responseHeaderSize
*/
public int getResponseHeaderSize()
{
return _responseHeaderSize;
}
/**
* @param responseHeaderSize the responseHeaderSize to set
*/
public void setResponseHeaderSize(int responseHeaderSize)
{
_responseHeaderSize = responseHeaderSize;
}
/**
* @return the requestBufferType
*/
public Buffers.Type getRequestBufferType()
{
return _requestBufferType;
}
/**
* @param requestBufferType the requestBufferType to set
*/
public void setRequestBufferType(Buffers.Type requestBufferType)
{
_requestBufferType = requestBufferType;
}
/**
* @return the requestHeaderType
*/
public Buffers.Type getRequestHeaderType()
{
return _requestHeaderType;
}
/**
* @param requestHeaderType the requestHeaderType to set
*/
public void setRequestHeaderType(Buffers.Type requestHeaderType)
{
_requestHeaderType = requestHeaderType;
}
/**
* @return the responseBufferType
*/
public Buffers.Type getResponseBufferType()
{
return _responseBufferType;
}
/**
* @param responseBufferType the responseBufferType to set
*/
public void setResponseBufferType(Buffers.Type responseBufferType)
{
_responseBufferType = responseBufferType;
}
/**
* @return the responseHeaderType
*/
public Buffers.Type getResponseHeaderType()
{
return _responseHeaderType;
}
/**
* @param responseHeaderType the responseHeaderType to set
*/
public void setResponseHeaderType(Buffers.Type responseHeaderType)
{
_responseHeaderType = responseHeaderType;
}
/**
* @param requestBuffers the requestBuffers to set
*/
public void setRequestBuffers(Buffers requestBuffers)
{
_requestBuffers = requestBuffers;
}
/**
* @param responseBuffers the responseBuffers to set
*/
public void setResponseBuffers(Buffers responseBuffers)
{
_responseBuffers = responseBuffers;
}
@Override
protected void doStart()
throws Exception
{
_requestBuffers=BuffersFactory.newBuffers(_requestHeaderType,_requestHeaderSize,_requestBufferType,_requestBufferSize,_requestBufferType,getMaxBuffers());
_responseBuffers=BuffersFactory.newBuffers(_responseHeaderType,_responseHeaderSize,_responseBufferType,_responseBufferSize,_responseBufferType,getMaxBuffers());
super.doStart();
}
@Override
protected void doStop()
throws Exception
{
_requestBuffers=null;
_responseBuffers=null;
}
public Buffers getRequestBuffers()
{
return _requestBuffers;
}
public Buffers getResponseBuffers()
{
return _responseBuffers;
}
public void setMaxBuffers(int maxBuffers)
{
_maxBuffers = maxBuffers;
}
public int getMaxBuffers()
{
return _maxBuffers;
}
public String toString()
{
return _requestBuffers+"/"+_responseBuffers;
}
}

View File

@ -2,6 +2,7 @@ package org.eclipse.jetty.io;
import org.eclipse.jetty.io.nio.DirectNIOBuffer;
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
import org.omg.stub.java.rmi._Remote_Stub;
public abstract class AbstractBuffers implements Buffers
{
@ -141,5 +142,10 @@ public abstract class AbstractBuffers implements Buffers
}
return false;
}
/* ------------------------------------------------------------ */
public String toString()
{
return this.getClass().getSimpleName()+"["+_headerSize+","+_bufferSize+"]";
}
}

View File

@ -92,4 +92,13 @@ public class PooledBuffers extends AbstractBuffers
_others.add(buffer);
}
}
public String toString()
{
return this.getClass().getSimpleName()+
"["+
_headers.size()+"/"+_maxSize+"@"+_headerSize+","+
_buffers.size()+"/"+_maxSize+"@"+_bufferSize+","+
_others.size()+"/"+_maxSize+"@-]";
}
}

View File

@ -938,6 +938,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
final ArrayList<Object> dump = new ArrayList<Object>(selector.keys().size()*2);
dump.add(where);
/*
final CountDownLatch latch = new CountDownLatch(1);
addChange(new ChangeTask()
@ -957,6 +958,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
LOG.ignore(e);
}
*/
AggregateLifeCycle.dump(out,indent,dump);
}
}

View File

@ -31,6 +31,7 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.log.Log;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@ -87,7 +88,8 @@ public class ProxyRuleTest
@Test
public void testProxy() throws Exception
{
Log.getLogger("org.eclipse.jetty.client").setDebugEnabled(true);
ContentExchange exchange = new ContentExchange(true);
exchange.setMethod(HttpMethods.GET);
String body = "BODY";

View File

@ -22,9 +22,12 @@ import java.util.concurrent.atomic.AtomicLong;
import javax.servlet.ServletRequest;
import org.eclipse.jetty.http.HttpBuffers;
import org.eclipse.jetty.http.HttpBuffersImpl;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.Buffers.Type;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
@ -51,7 +54,7 @@ import org.eclipse.jetty.util.thread.ThreadPool;
*
*
*/
public abstract class AbstractConnector extends HttpBuffers implements Connector, Dumpable
public abstract class AbstractConnector extends AggregateLifeCycle implements HttpBuffers, Connector, Dumpable
{
private static final Logger LOG = Log.getLogger(AbstractConnector.class);
@ -95,11 +98,14 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/** duration of a connection */
private final SampleStatistic _connectionDurationStats = new SampleStatistic();
protected final HttpBuffersImpl _buffers = new HttpBuffersImpl();
/* ------------------------------------------------------------ */
/**
*/
public AbstractConnector()
{
addBean(_buffers);
}
/* ------------------------------------------------------------ */
@ -125,7 +131,9 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
public void setThreadPool(ThreadPool pool)
{
removeBean(_threadPool);
_threadPool = pool;
addBean(_threadPool);
}
/* ------------------------------------------------------------ */
@ -299,12 +307,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
// open listener port
open();
super.doStart();
if (_threadPool == null)
{
_threadPool = _server.getThreadPool();
if (_threadPool != _server.getThreadPool() && (_threadPool instanceof LifeCycle))
((LifeCycle)_threadPool).start();
addBean(_threadPool,false);
}
super.doStart();
// Start selector thread
synchronized (this)
@ -333,9 +342,6 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
LOG.warn(e);
}
if (_threadPool != _server.getThreadPool() && _threadPool instanceof LifeCycle)
((LifeCycle)_threadPool).stop();
super.doStop();
Thread[] acceptors = null;
@ -785,6 +791,98 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{
_forwardedSslSessionIdHeader = forwardedSslSessionId;
}
public int getRequestBufferSize()
{
return _buffers.getRequestBufferSize();
}
public void setRequestBufferSize(int requestBufferSize)
{
_buffers.setRequestBufferSize(requestBufferSize);
}
public int getRequestHeaderSize()
{
return _buffers.getRequestHeaderSize();
}
public void setRequestHeaderSize(int requestHeaderSize)
{
_buffers.setRequestHeaderSize(requestHeaderSize);
}
public int getResponseBufferSize()
{
return _buffers.getResponseBufferSize();
}
public void setResponseBufferSize(int responseBufferSize)
{
_buffers.setResponseBufferSize(responseBufferSize);
}
public int getResponseHeaderSize()
{
return _buffers.getResponseHeaderSize();
}
public void setResponseHeaderSize(int responseHeaderSize)
{
_buffers.setResponseHeaderSize(responseHeaderSize);
}
public Type getRequestBufferType()
{
return _buffers.getRequestBufferType();
}
public Type getRequestHeaderType()
{
return _buffers.getRequestHeaderType();
}
public Type getResponseBufferType()
{
return _buffers.getResponseBufferType();
}
public Type getResponseHeaderType()
{
return _buffers.getResponseHeaderType();
}
public void setRequestBuffers(Buffers requestBuffers)
{
_buffers.setRequestBuffers(requestBuffers);
}
public void setResponseBuffers(Buffers responseBuffers)
{
_buffers.setResponseBuffers(responseBuffers);
}
public Buffers getRequestBuffers()
{
return _buffers.getRequestBuffers();
}
public Buffers getResponseBuffers()
{
return _buffers.getResponseBuffers();
}
public void setMaxBuffers(int maxBuffers)
{
_buffers.setMaxBuffers(maxBuffers);
}
public int getMaxBuffers()
{
return _buffers.getMaxBuffers();
}
/* ------------------------------------------------------------ */
@Override
@ -1118,17 +1216,4 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
oldValue = valueHolder.get();
}
}
/* ------------------------------------------------------------ */
public String dump()
{
return AggregateLifeCycle.dump(this);
}
/* ------------------------------------------------------------ */
public void dump(Appendable out, String indent) throws IOException
{
out.append(String.valueOf(this)).append("\n");
}
}

View File

@ -27,10 +27,10 @@ import org.eclipse.jetty.server.AbstractConnector;
public abstract class AbstractNIOConnector extends AbstractConnector implements NIOConnector
{
{
setRequestBufferType(Type.DIRECT);
setRequestHeaderType(Type.INDIRECT);
setResponseBufferType(Type.DIRECT);
setResponseHeaderType(Type.INDIRECT);
_buffers.setRequestBufferType(Type.DIRECT);
_buffers.setRequestHeaderType(Type.INDIRECT);
_buffers.setResponseBufferType(Type.DIRECT);
_buffers.setResponseHeaderType(Type.INDIRECT);
}
/* ------------------------------------------------------------------------------- */
@ -46,8 +46,8 @@ public abstract class AbstractNIOConnector extends AbstractConnector implements
*/
public void setUseDirectBuffers(boolean direct)
{
setRequestBufferType(direct?Type.DIRECT:Type.INDIRECT);
setResponseBufferType(direct?Type.DIRECT:Type.INDIRECT);
_buffers.setRequestBufferType(direct?Type.DIRECT:Type.INDIRECT);
_buffers.setResponseBufferType(direct?Type.DIRECT:Type.INDIRECT);
}
}

View File

@ -82,6 +82,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
public SelectChannelConnector()
{
_manager.setMaxIdleTime(getMaxIdleTime());
addBean(_manager,true);
setAcceptors(Math.max(1,(Runtime.getRuntime().availableProcessors()+3)/4));
}
@ -111,7 +112,11 @@ public class SelectChannelConnector extends AbstractNIOConnector
synchronized(this)
{
if (_acceptChannel != null)
_acceptChannel.close();
{
removeBean(_acceptChannel);
if (_acceptChannel.isOpen())
_acceptChannel.close();
}
_acceptChannel = null;
_localPort=-2;
}
@ -177,6 +182,8 @@ public class SelectChannelConnector extends AbstractNIOConnector
_localPort=_acceptChannel.socket().getLocalPort();
if (_localPort<=0)
throw new IOException("Server channel not bound");
addBean(_acceptChannel);
}
}
@ -250,7 +257,6 @@ public class SelectChannelConnector extends AbstractNIOConnector
_manager.setLowResourcesMaxIdleTime(getLowResourcesMaxIdleTime());
super.doStart();
_manager.start();
}
/* ------------------------------------------------------------ */
@ -260,20 +266,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
@Override
protected void doStop() throws Exception
{
synchronized(this)
{
if(_manager.isRunning())
{
try
{
_manager.stop();
}
catch (Exception e)
{
LOG.warn(e);
}
}
}
close();
super.doStop();
}
@ -297,20 +290,6 @@ public class SelectChannelConnector extends AbstractNIOConnector
return new AsyncHttpConnection(SelectChannelConnector.this,endpoint,getServer());
}
/* ------------------------------------------------------------ */
public void dump(Appendable out, String indent) throws IOException
{
super.dump(out, indent);
ServerSocketChannel channel;
synchronized (this)
{
channel=_acceptChannel;
}
if (channel==null)
AggregateLifeCycle.dump(out,indent,Arrays.asList(null,"CLOSED",_manager));
else
AggregateLifeCycle.dump(out,indent,Arrays.asList(channel,channel.isOpen()?"OPEN":"CLOSED",_manager));
}
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */

View File

@ -57,6 +57,7 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
public SslSelectChannelConnector(SslContextFactory sslContextFactory)
{
_sslContextFactory = sslContextFactory;
addBean(_sslContextFactory);
setUseDirectBuffers(false);
setSoLingerTime(30000);
}
@ -597,7 +598,6 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
protected void doStart() throws Exception
{
_sslContextFactory.checkKeyStore();
_sslContextFactory.start();
SSLEngine sslEngine = _sslContextFactory.newSslEngine();
@ -627,7 +627,6 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements
@Override
protected void doStop() throws Exception
{
_sslContextFactory.stop();
_sslBuffers=null;
super.doStop();
}

View File

@ -12,92 +12,242 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* An AggregateLifeCycle is an AbstractLifeCycle with a collection of dependent beans.
* An AggregateLifeCycle is an {@link LifeCycle} implementation for a collection of contained beans.
* <p>
* Beans can be added the AggregateLifeCycle either as joined beans, as disjoint beans. A joined bean is started, stopped and destroyed with the aggregate.
* A disjointed bean is associated with the aggregate for the purposes of {@link #dump()}, but it's lifecycle must be managed externally.
* <p>
* When a bean is added, if it is a {@link LifeCycle} and it is already started, then it is assumed to be a disjoined bean.
* Otherwise the methods {@link #addBean(LifeCycle, boolean)}, {@link #join(LifeCycle)} and {@link #disjoin(LifeCycle)} can be used to
* explicitly control the life cycle relationship.
* <p>
* Dependent beans are started and stopped with the {@link LifeCycle} and if they are destroyed if they are also {@link Destroyable}.
*
*/
public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable, Dumpable
{
private static final Logger LOG = Log.getLogger(AggregateLifeCycle.class);
private final List<Object> _dependentBeans=new CopyOnWriteArrayList<Object>();
private final List<Bean> _beans=new CopyOnWriteArrayList<Bean>();
public void destroy()
private class Bean
{
for (Object o : _dependentBeans)
Bean(Object b)
{
if (o instanceof Destroyable)
{
((Destroyable)o).destroy();
}
_bean=b;
}
_dependentBeans.clear();
final Object _bean;
volatile boolean _joined=true;
}
/* ------------------------------------------------------------ */
/**
* Start the joined lifecycle beans in the order they were added.
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
*/
@Override
protected void doStart() throws Exception
{
for (Object o:_dependentBeans)
for (Bean b:_beans)
{
if (o instanceof LifeCycle)
((LifeCycle)o).start();
if (b._joined && b._bean instanceof LifeCycle)
{
LifeCycle l=(LifeCycle)b._bean;
if (!l.isRunning())
l.start();
}
}
super.doStart();
}
/* ------------------------------------------------------------ */
/**
* Stop the joined lifecycle beans in the reverse order they were added.
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
*/
@Override
protected void doStop() throws Exception
{
super.doStop();
List<Object> reverse = new ArrayList<Object>(_dependentBeans);
List<Bean> reverse = new ArrayList<Bean>(_beans);
Collections.reverse(reverse);
for (Object o:reverse)
for (Bean b:reverse)
{
if (o instanceof LifeCycle)
((LifeCycle)o).stop();
if (b._joined && b._bean instanceof LifeCycle)
{
LifeCycle l=(LifeCycle)b._bean;
if (l.isRunning())
l.stop();
}
}
}
/* ------------------------------------------------------------ */
/**
* Destroy the joined Destroyable beans in the reverse order they were added.
* @see org.eclipse.jetty.util.component.Destroyable#destroy()
*/
public void destroy()
{
List<Bean> reverse = new ArrayList<Bean>(_beans);
Collections.reverse(reverse);
for (Bean b:reverse)
{
if (b._bean instanceof Destroyable && b._joined)
{
Destroyable d=(Destroyable)b._bean;
d.destroy();
}
}
_beans.clear();
}
/* ------------------------------------------------------------ */
/** Is the bean contained in the aggregate.
* @param bean
* @return True if the aggregate contains the bean
*/
public boolean contains(Object bean)
{
for (Bean b:_beans)
if (b._bean==bean)
return true;
return false;
}
/* ------------------------------------------------------------ */
/** Is the bean joined to the aggregate.
* @param bean
* @return True if the aggregate contains the bean and it is joined
*/
public boolean isJoined(Object bean)
{
for (Bean b:_beans)
if (b._bean==bean)
return b._joined;
return false;
}
/* ------------------------------------------------------------ */
/**
* Add an associated bean.
* The bean will be added to this LifeCycle and if it is also a
* {@link LifeCycle} instance, it will be
* started/stopped. Any beans that are also
* {@link Destroyable}, will be destroyed with the server.
* If the bean is a {@link LifeCycle}, it is added as neither joined or disjoint and
* that status will be determined when the Aggregate bean is started.
* @param o the bean object to add
* @return true if the bean was added or false if it has already been added.
*/
public boolean addBean(Object o)
{
if (o == null)
if (contains(o))
return false;
boolean added=false;
if (!_dependentBeans.contains(o))
Bean b = new Bean(o);
_beans.add(b);
// extra LifeCycle handling
if (o instanceof LifeCycle)
{
_dependentBeans.add(o);
added=true;
LifeCycle l=(LifeCycle)o;
// If it is running, then assume it is disjoint
if (l.isRunning())
b._joined=false;
// else if we are running, then start the bean
else if (isRunning())
{
try
{
l.start();
}
catch(Exception e)
{
throw new RuntimeException (e);
}
}
}
try
return true;
}
/* ------------------------------------------------------------ */
/** Add an associated lifecycle.
* @param o The lifecycle to add
* @param joined True if the LifeCycle is to be joined, otherwise it will be disjoint.
* @return
*/
public boolean addBean(Object o, boolean joined)
{
if (contains(o))
return false;
Bean b = new Bean(o);
b._joined=joined;
_beans.add(b);
if (o instanceof LifeCycle)
{
if (isStarted() && o instanceof LifeCycle)
((LifeCycle)o).start();
LifeCycle l=(LifeCycle)o;
if (joined && isRunning())
{
try
{
l.start();
}
catch(Exception e)
{
throw new RuntimeException (e);
}
}
}
catch (Exception e)
return true;
}
/* ------------------------------------------------------------ */
/**
* Join a bean to this aggregate, so that it is started/stopped/destroyed with the
* aggregate lifecycle.
* @param bean The bean to join (must already have been added).
*/
public void join(Object bean)
{
for (Bean b :_beans)
{
throw new RuntimeException (e);
if (b._bean==bean)
{
b._joined=true;
return;
}
}
return added;
throw new IllegalArgumentException();
}
/* ------------------------------------------------------------ */
/**
* Disjoin a bean to this aggregate, so that it is not started/stopped/destroyed with the
* aggregate lifecycle.
* @param bean The bean to join (must already have been added).
*/
public void disjoin(Object bean)
{
for (Bean b :_beans)
{
if (b._bean==bean)
{
b._joined=false;
return;
}
}
throw new IllegalArgumentException();
}
/* ------------------------------------------------------------ */
/** Get dependent beans
* @return List of beans.
*/
public Collection<Object> getBeans()
{
return _dependentBeans;
return getBeans(Object.class);
}
/* ------------------------------------------------------------ */
@ -109,19 +259,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
public <T> List<T> getBeans(Class<T> clazz)
{
ArrayList<T> beans = new ArrayList<T>();
Iterator<?> iter = _dependentBeans.iterator();
while (iter.hasNext())
for (Bean b:_beans)
{
Object o = iter.next();
if (clazz.isInstance(o))
beans.add((T)o);
if (clazz.isInstance(b._bean))
beans.add((T)(b._bean));
}
return beans;
}
/* ------------------------------------------------------------ */
/** Get dependent bean of a specific class.
/** Get dependent beans of a specific class.
* If more than one bean of the type exist, the first is returned.
* @see #addBean(Object)
* @param clazz
@ -129,23 +277,13 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
*/
public <T> T getBean(Class<T> clazz)
{
Iterator<?> iter = _dependentBeans.iterator();
T t=null;
int count=0;
while (iter.hasNext())
for (Bean b:_beans)
{
Object o = iter.next();
if (clazz.isInstance(o))
{
count++;
if (t==null)
t=(T)o;
}
if (clazz.isInstance(b._bean))
return (T)b._bean;
}
if (count>1 && LOG.isDebugEnabled())
LOG.debug("getBean({}) 1 of {}",clazz.getName(),count);
return t;
return null;
}
/* ------------------------------------------------------------ */
@ -154,7 +292,7 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
*/
public void removeBeans ()
{
_dependentBeans.clear();
_beans.clear();
}
/* ------------------------------------------------------------ */
@ -163,9 +301,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
*/
public boolean removeBean (Object o)
{
if (o == null)
return false;
return _dependentBeans.remove(o);
Iterator<Bean> i = _beans.iterator();
while(i.hasNext())
{
Bean b=i.next();
if (b._bean==o)
{
_beans.remove(b);
return true;
}
}
return false;
}
/* ------------------------------------------------------------ */
@ -218,7 +364,32 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
public void dump(Appendable out,String indent) throws IOException
{
dumpThis(out);
dump(out,indent,_dependentBeans);
int size=_beans.size();
if (size==0)
return;
int i=0;
for (Bean b : _beans)
{
i++;
if (b._joined)
{
out.append(indent).append(" +- ");
if (b._bean instanceof Dumpable)
((Dumpable)b._bean).dump(out,indent+(i==size?" ":" | "));
else
out.append(String.valueOf(b._bean)).append("\n");
}
else
{
out.append(indent).append(" +~ ");
out.append(String.valueOf(b._bean)).append("\n");
}
}
if (i!=size)
out.append(indent).append(" |\n");
}
/* ------------------------------------------------------------ */

View File

@ -1521,5 +1521,11 @@ public class SslContextFactory extends AbstractLifeCycle
sslEngine.setEnabledProtocols(selectProtocols(sslEngine.getEnabledProtocols(),sslEngine.getSupportedProtocols()));
}
/* ------------------------------------------------------------ */
public String toString()
{
return this.getClass().getSimpleName()+"@"+Integer.toHexString(hashCode())+
"("+_keyStorePath+","+_trustStorePath+")#"+getState();
}
}

View File

@ -110,6 +110,107 @@ public class AggregateLifeCycleTest
}
@Test
public void testDisJoint() throws Exception
{
final AtomicInteger destroyed=new AtomicInteger();
final AtomicInteger started=new AtomicInteger();
final AtomicInteger stopped=new AtomicInteger();
AggregateLifeCycle a0=new AggregateLifeCycle();
AggregateLifeCycle a1=new AggregateLifeCycle()
{
@Override
protected void doStart() throws Exception
{
started.incrementAndGet();
super.doStart();
}
@Override
protected void doStop() throws Exception
{
stopped.incrementAndGet();
super.doStop();
}
@Override
public void destroy()
{
destroyed.incrementAndGet();
super.destroy();
}
};
// Start the a1 bean before adding, makes it auto disjoint
a1.start();
// Now add it
a0.addBean(a1);
Assert.assertFalse(a0.isJoined(a1));
a0.start();
Assert.assertEquals(1,started.get());
Assert.assertEquals(0,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.start();
Assert.assertEquals(1,started.get());
Assert.assertEquals(0,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.stop();
Assert.assertEquals(1,started.get());
Assert.assertEquals(0,stopped.get());
Assert.assertEquals(0,destroyed.get());
a1.stop();
Assert.assertEquals(1,started.get());
Assert.assertEquals(1,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.start();
Assert.assertEquals(1,started.get());
Assert.assertEquals(1,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.join(a1);
Assert.assertTrue(a0.isJoined(a1));
a0.stop();
Assert.assertEquals(1,started.get());
Assert.assertEquals(1,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.start();
Assert.assertEquals(2,started.get());
Assert.assertEquals(1,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.stop();
Assert.assertEquals(2,started.get());
Assert.assertEquals(2,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.disjoin(a1);
Assert.assertFalse(a0.isJoined(a1));
a0.destroy();
Assert.assertEquals(2,started.get());
Assert.assertEquals(2,stopped.get());
Assert.assertEquals(0,destroyed.get());
a1.destroy();
Assert.assertEquals(2,started.get());
Assert.assertEquals(2,stopped.get());
Assert.assertEquals(1,destroyed.get());
}
@Test
public void testDumpable()
{
@ -159,6 +260,11 @@ public class AggregateLifeCycleTest
System.err.println("--");
a2.addBean(aa0);
a0.dumpStdErr();
System.err.println("--");
a0.disjoin(aa);
a2.disjoin(aa0);
a0.dumpStdErr();
}
}