📄 httpservletmessenger.java
字号:
/* * * $Id: HttpServletMessenger.java,v 1.26 2006/05/11 17:54:57 hamada Exp $ * * Copyright (c) 2001 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Sun Microsystems, Inc. for Project JXTA." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" * must not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact Project JXTA at http://www.jxta.org. * * 5. Products derived from this software may not be called "JXTA", * nor may "JXTA" appear in their name, without prior written * permission of Sun. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL SUN MICROSYSTEMS OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of Project JXTA. For more * information on Project JXTA, please see * <http://www.jxta.org/>. * * This license is based on the BSD license adopted by the Apache Foundation. */package net.jxta.impl.endpoint.servlethttp;import java.util.Timer;import java.util.TimerTask;import java.io.IOException;import org.apache.log4j.Level;import org.apache.log4j.Logger;import net.jxta.endpoint.EndpointAddress;import net.jxta.endpoint.Message;import net.jxta.endpoint.MessageElement;import net.jxta.endpoint.StringMessageElement;import net.jxta.peergroup.PeerGroupID;import net.jxta.impl.endpoint.BlockingMessenger;import net.jxta.impl.endpoint.EndpointServiceImpl;import net.jxta.impl.util.TimeUtils;/** * Simple messenger that waits for a message to give back to the requesting client * * <p/>This messenger is not entirely thread-safe. You should not use any * of the <code>sendMessage</code> methods from more than one thread. * **/final class HttpServletMessenger extends BlockingMessenger { /** * Log4J Logger **/ private final static transient Logger LOG = Logger.getLogger(HttpServletMessenger.class.getName()); // We need an explicit idle state. outgoingMessage being null is not enough // because there is an intermediate state where the http servlet must know // that there is nothing new to be sent but the relay side must also know // that status has not been collected yet (the messenger is not ready to be // reused). We use outgoingMessage == null to know that the message // has already been picked-up by the servlet thread, and // sendResult != IDLE to know that the result has not yet been collected // by the relay sender thread. private final static int SEND_IDLE = 0; private final static int SEND_INPROGRESS = 1; private final static int SEND_SUCCESS = 2; private final static int SEND_FAIL = 3; private final static int SEND_TOOLONG = 4; private final static long MAX_SENDING_BLOCK = 2 * TimeUtils.AMINUTE; private final static long MAX_SENDING_WAIT = 3 * TimeUtils.ASECOND; private final static EndpointAddress nullEndpointAddr = EndpointAddress.unmodifiableEndpointAddress( new EndpointAddress("http", "0.0.0.0:0", null, null) ); private final static Timer closeMessengerTimer = new Timer( "HttpServletMessenger Expiration timer", true); private final EndpointAddress logicalAddress; private final MessageElement srcAddressElement; private ScheduledExipry expirationTask; /** * The message "queue" **/ private Message outgoingMessage = null; private int sendResult = SEND_IDLE; private long sendingSince = 0; /** * Allows us to schedule the closing of a messenger. **/ private static class ScheduledExipry extends TimerTask { /** * The messenger we will be expiring. **/ HttpServletMessenger messenger; ScheduledExipry( HttpServletMessenger toExpire ) { messenger = toExpire; } /** * {@inheritDoc} **/ public boolean cancel() { // It is important we clear the messenger because Timer doesn't // remove cancelled TimerTasks from it's queue until they fire. This // means that the Messenger would not be GCed until the TimerTask // fired. messenger = null; boolean result = super.cancel(); // take the opportunity to also purge canceled tasks closeMessengerTimer.purge(); return result; } /** * {@inheritDoc} **/ public void run( ) { try { HttpServletMessenger temp = messenger; messenger = null; if( null != temp ) { temp.close(); } } catch( Throwable all ) { if (LOG.isEnabledFor(Level.FATAL)) { LOG.fatal("Uncaught Throwable in timer task :" + Thread.currentThread().getName(), all); } } } } /** * Standard constructor. **/ HttpServletMessenger(PeerGroupID peerGroupID, EndpointAddress srcAddress, EndpointAddress logicalAddress, long validFor ) { // We do not use self destruction. super(peerGroupID, nullEndpointAddr, false); this.logicalAddress = logicalAddress; this.srcAddressElement = new StringMessageElement(EndpointServiceImpl.MESSAGE_SOURCE_NAME, srcAddress.toString(), null); if( (0 != validFor) && (validFor < Long.MAX_VALUE) ) { expirationTask = new ScheduledExipry(this); closeMessengerTimer.schedule( expirationTask, validFor ); } if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("HttpServletMessenger\n\t" + toString()); } } /** * {@inheritDoc} **/ public synchronized void closeImpl() { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("close\n\t" + toString()); } ScheduledExipry cancelExpire = expirationTask; expirationTask = null; if( null != cancelExpire ) { cancelExpire.cancel(); } super.close(); notifyAll(); } /** * {@inheritDoc} **/ public EndpointAddress getLogicalDestinationImpl() { return (EndpointAddress) logicalAddress.clone(); } /** * {@inheritDoc} **/ public boolean isIdleImpl() { // We do not use self destruction. return false; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -