?? selectchannelconnector.java
字號:
// ========================================================================// Copyright 2003-2005 Mort Bay Consulting Pty. Ltd.// ------------------------------------------------------------------------// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// ========================================================================package org.mortbay.jetty.nio;import java.io.IOException;import java.net.InetSocketAddress;import java.net.Socket;import java.nio.channels.SelectionKey;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import org.mortbay.io.Connection;import org.mortbay.io.nio.SelectChannelEndPoint;import org.mortbay.io.nio.SelectorManager;import org.mortbay.io.nio.SelectorManager.SelectSet;import org.mortbay.jetty.HttpConnection;import org.mortbay.jetty.Request;import org.mortbay.jetty.RetryRequest;import org.mortbay.log.Log;import org.mortbay.thread.Timeout;import org.mortbay.util.ajax.Continuation;/* ------------------------------------------------------------------------------- *//** * Selecting NIO connector. * <p> * This connector uses efficient NIO buffers with a non blocking threading model. Direct NIO buffers * are used and threads are only allocated to connections with requests. Synchronization is used to * simulate blocking for the servlet API, and any unflushed content at the end of request handling * is written asynchronously. * </p> * <p> * This connector is best used when there are a many connections that have idle periods. * </p> * <p> * When used with {@link org.mortbay.util.ajax.Continuation}, threadless waits are supported. When * a filter or servlet calls getEvent on a Continuation, a {@link org.mortbay.jetty.RetryRequest} * runtime exception is thrown to allow the thread to exit the current request handling. Jetty will * catch this exception and will not send a response to the client. Instead the thread is released * and the Continuation is placed on the timer queue. If the Continuation timeout expires, or it's * resume method is called, then the request is again allocated a thread and the request is retried. * The limitation of this approach is that request content is not available on the retried request, * thus if possible it should be read after the continuation or saved as a request attribute or as the * associated object of the Continuation instance. * </p> * * @org.apache.xbean.XBean element="nioConnector" description="Creates an NIO based socket connector" * * @author gregw * */public class SelectChannelConnector extends AbstractNIOConnector { private transient ServerSocketChannel _acceptChannel; private long _lowResourcesConnections; private long _lowResourcesMaxIdleTime; private SelectorManager _manager = new SelectorManager() { protected SocketChannel acceptChannel(SelectionKey key) throws IOException { // TODO handle max connections SocketChannel channel = ((ServerSocketChannel)key.channel()).accept(); if (channel==null) return null; channel.configureBlocking(false); Socket socket = channel.socket(); configure(socket); return channel; } public boolean dispatch(Runnable task) throws IOException { return getThreadPool().dispatch(task); } protected void endPointClosed(SelectChannelEndPoint endpoint) { // TODO handle max connections and low resources connectionClosed((HttpConnection)endpoint.getConnection()); } protected void endPointOpened(SelectChannelEndPoint endpoint) { // TODO handle max connections and low resources connectionOpened((HttpConnection)endpoint.getConnection()); } protected Connection newConnection(SocketChannel channel,SelectChannelEndPoint endpoint) { return SelectChannelConnector.this.newConnection(channel,endpoint); } protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey sKey) throws IOException { return SelectChannelConnector.this.newEndPoint(channel,selectSet,sKey); } }; /* ------------------------------------------------------------------------------- */ /** * Constructor. * */ public SelectChannelConnector() { } /* ------------------------------------------------------------ */ public void accept(int acceptorID) throws IOException { _manager.doSelect(acceptorID); } /* ------------------------------------------------------------ */ public void close() throws IOException { synchronized(this) { if (_acceptChannel != null) _acceptChannel.close(); _acceptChannel = null; } } /* ------------------------------------------------------------------------------- */ public void customize(org.mortbay.io.EndPoint endpoint, Request request) throws IOException { ConnectorEndPoint cep = ((ConnectorEndPoint)endpoint); cep.cancelIdle(); request.setTimeStamp(cep.getSelectSet().getNow()); super.customize(endpoint, request); } /* ------------------------------------------------------------------------------- */ public void persist(org.mortbay.io.EndPoint endpoint) throws IOException { ((ConnectorEndPoint)endpoint).scheduleIdle(); super.persist(endpoint); } /* ------------------------------------------------------------ */ public Object getConnection() { return _acceptChannel; } /* ------------------------------------------------------------ */ /** Get delay select key update * If true, the select set is not updated when a endpoint is dispatched for * reading. The assumption is that the task will be short and thus will probably * be complete before the select is tried again. * @return Returns the assumeShortDispatch. */ public boolean getDelaySelectKeyUpdate() { return _manager.isDelaySelectKeyUpdate(); } /* ------------------------------------------------------------------------------- */ public int getLocalPort() { synchronized(this) { if (_acceptChannel==null || !_acceptChannel.isOpen()) return -1; return _acceptChannel.socket().getLocalPort(); } } /* ------------------------------------------------------------ */ /* * @see org.mortbay.jetty.Connector#newContinuation() */ public Continuation newContinuation() { return new RetryContinuation(); } /* ------------------------------------------------------------ */ public void open() throws IOException { synchronized(this) { if (_acceptChannel == null) { // Create a new server socket _acceptChannel = ServerSocketChannel.open(); // Bind the server socket to the local host and port _acceptChannel.socket().setReuseAddress(getReuseAddress()); InetSocketAddress addr = getHost()==null?new InetSocketAddress(getPort()):new InetSocketAddress(getHost(),getPort()); _acceptChannel.socket().bind(addr,getAcceptQueueSize()); // Set to non blocking mode _acceptChannel.configureBlocking(false); } } } /* ------------------------------------------------------------ */ /** * @param delay If true, updating a {@link SelectionKey} is delayed until a redundant event is * schedules. This is an optimization that assumes event handling can be completed before the next select * completes. */ public void setDelaySelectKeyUpdate(boolean delay) { _manager.setDelaySelectKeyUpdate(delay); } /* ------------------------------------------------------------ */ public void setMaxIdleTime(int maxIdleTime) { _manager.setMaxIdleTime(maxIdleTime); super.setMaxIdleTime(maxIdleTime); } /* ------------------------------------------------------------ */ /** * @return the lowResourcesConnections */ public long getLowResourcesConnections() { return _lowResourcesConnections; } /* ------------------------------------------------------------ */ /** * Set the number of connections, which if exceeded places this manager in low resources state. * This is not an exact measure as the connection count is averaged over the select sets. * @param lowResourcesConnections the number of connections * @see {@link #setLowResourcesMaxIdleTime(long)} */ public void setLowResourcesConnections(long lowResourcesConnections) { _lowResourcesConnections=lowResourcesConnections; } /* ------------------------------------------------------------ */ /** * @return the lowResourcesMaxIdleTime */ public long getLowResourcesMaxIdleTime() { return _lowResourcesMaxIdleTime; } /* ------------------------------------------------------------ */ /** * Set the period in ms that a connection is allowed to be idle when this there are more * than {@link #getLowResourcesConnections()} connections. This allows the server to rapidly close idle connections * in order to gracefully handle high load situations. * @param lowResourcesMaxIdleTime the period in ms that a connection is allowed to be idle when resources are low. * @see {@link #setMaxIdleTime(long)} * @deprecated use {@link #setLowResourceMaxIdleTime(int)} */ public void setLowResourcesMaxIdleTime(long lowResourcesMaxIdleTime) { _lowResourcesMaxIdleTime=lowResourcesMaxIdleTime; super.setLowResourceMaxIdleTime((int)lowResourcesMaxIdleTime); // TODO fix the name duplications } /* ------------------------------------------------------------ */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -