Return-Path: Delivered-To: apmail-ws-axis-dev-archive@www.apache.org Received: (qmail 19328 invoked from network); 7 Nov 2006 05:52:46 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 7 Nov 2006 05:52:46 -0000 Received: (qmail 33437 invoked by uid 500); 7 Nov 2006 05:52:57 -0000 Delivered-To: apmail-ws-axis-dev-archive@ws.apache.org Received: (qmail 33178 invoked by uid 500); 7 Nov 2006 05:52:55 -0000 Mailing-List: contact axis-cvs-help@ws.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list axis-cvs@ws.apache.org Received: (qmail 33165 invoked by uid 500); 7 Nov 2006 05:52:55 -0000 Delivered-To: apmail-ws-axis2-cvs@ws.apache.org Received: (qmail 33159 invoked by uid 99); 7 Nov 2006 05:52:55 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 06 Nov 2006 21:52:55 -0800 X-ASF-Spam-Status: No, hits=-8.6 required=10.0 tests=ALL_TRUSTED,INFO_TLD,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 06 Nov 2006 21:52:43 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id 6D4AD1A9846; Mon, 6 Nov 2006 21:52:16 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r471995 - in /webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server: ConnectionListenerFailureHandler.java DefaultConnectionListener.java DefaultConnectionListenerFailureHandler.java Date: Tue, 07 Nov 2006 05:52:16 -0000 To: axis2-cvs@ws.apache.org From: chuckw@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20061107055216.6D4AD1A9846@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: chuckw Date: Mon Nov 6 21:52:15 2006 New Revision: 471995 URL: http://svn.apache.org/viewvc?view=rev&rev=471995 Log: Make the default connection listener thread in SimpleHttpServer more robust, solving a problem where a failure in this thread could leave an axis2 service quietly cut off from its clients. ConnectListenerFailureHandler provides an interface for managing exceptions in the connection listener thread. DefaultConnectionListenerFailureHandler tries to re-establish the listen several times before giving up, always logging the issues, and provides a notification mechanism if the thread ever terminates. This is all easily configurable through HttpFactory. Resolves AXIS2-1607 Added: webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/ConnectionListenerFailureHandler.java webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/DefaultConnectionListenerFailureHandler.java Modified: webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/DefaultConnectionListener.java Added: webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/ConnectionListenerFailureHandler.java URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/ConnectionListenerFailureHandler.java?view=auto&rev=471995 ============================================================================== --- webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/ConnectionListenerFailureHandler.java (added) +++ webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/ConnectionListenerFailureHandler.java Mon Nov 6 21:52:15 2006 @@ -0,0 +1,48 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * Copyright 1999-2006 The Apache Software Foundation + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.axis2.transport.http.server; + +public interface ConnectionListenerFailureHandler { + + /** The associated connection listener IOProcessor has failed + * @param connectionListener the associated connection listener + * @param cause cause of failure + * @return true if the listener should attempt to re-establish itself, false if it should terminate. + */ + public boolean failed(IOProcessor connectionListener, Throwable cause); + + /** The associated connection listener IOProcessor is terminating abnormally + * @param connectionListener the associated connection listener + * @param message explanation of termination + * @param cause last exception that is causing termination + */ + public void notifyAbnormalTermination(IOProcessor connectionListener, String message, Throwable cause); + +} Modified: webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/DefaultConnectionListener.java URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/DefaultConnectionListener.java?view=diff&rev=471995&r1=471994&r2=471995 ============================================================================== --- webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/DefaultConnectionListener.java (original) +++ webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/DefaultConnectionListener.java Mon Nov 6 21:52:15 2006 @@ -43,25 +43,34 @@ private static Log LOG = LogFactory.getLog(DefaultConnectionListener.class); private volatile boolean destroyed = false; - + + private final int port; private final HttpConnectionFactory connfactory; private final HttpConnectionManager connmanager; - private final ServerSocket serversocket; - - public DefaultConnectionListener( - int port, - final HttpConnectionFactory connfactory, - final HttpConnectionManager connmanager) throws IOException { + private ServerSocket serversocket; + private final ConnectionListenerFailureHandler failureHandler; + + /** Default constructor called by HttpFactory. A custom HttpFactory subclass can call the other constructor to provide a custom ConnectionListenerErrorHandler */ + public DefaultConnectionListener(int port, HttpConnectionFactory connfactory, HttpConnectionManager connmanager) throws IOException { + this(port, connfactory, connmanager, new DefaultConnectionListenerFailureHandler()); + } + + /** Use this constructor to provide a custom ConnectionListenerFailureHandler, e.g. by subclassing DefaultConnectionListenerFailureHandler */ + public DefaultConnectionListener(int port, HttpConnectionFactory connfactory, HttpConnectionManager connmanager, + ConnectionListenerFailureHandler failureHandler) + throws IOException { super(); - if (connfactory == null) { + if (connfactory == null) throw new IllegalArgumentException("Connection factory may not be null"); - } - if (connmanager == null) { + if (connmanager == null) throw new IllegalArgumentException("Connection manager may not be null"); - } + if (failureHandler == null) + throw new IllegalArgumentException("Failure handler may not be null"); + this.port = port; this.connmanager = connmanager; this.connfactory = connfactory; this.serversocket = new ServerSocket(port); + this.failureHandler = failureHandler; } public void run() { @@ -69,8 +78,10 @@ LOG.info("Listening on port " + this.serversocket.getLocalPort()); } try { - while (!this.serversocket.isClosed() && !Thread.interrupted()) { + while (!Thread.interrupted()) { try { + if (serversocket.isClosed()) + serversocket = new ServerSocket(port); LOG.debug("Waiting for incoming HTTP connection"); Socket socket = this.serversocket.accept(); if (LOG.isDebugEnabled()) { @@ -79,23 +90,11 @@ } HttpServerConnection conn = this.connfactory.newConnection(socket); this.connmanager.process(conn); - } catch (IOException ex) { - if (ex instanceof SocketException) { - if (LOG.isDebugEnabled() - && !this.destroyed && !Thread.interrupted()) { - LOG.debug("Connection listener terminated due to an I/O error: " + - ex.getMessage()); - } - } else { - if (LOG.isWarnEnabled()) { - LOG.warn("Connection listener terminated due to an I/O error: " + - ex.getMessage(), ex); - } - } - break; } catch (Throwable ex) { - LOG.error("Connection listener terminated due to a runtime error", ex); - break; + if (Thread.interrupted()) + break; + if (!failureHandler.failed(this, ex)) + break; } } } finally { Added: webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/DefaultConnectionListenerFailureHandler.java URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/DefaultConnectionListenerFailureHandler.java?view=auto&rev=471995 ============================================================================== --- webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/DefaultConnectionListenerFailureHandler.java (added) +++ webservices/axis2/branches/java/1_1/modules/kernel/src/org/apache/axis2/transport/http/server/DefaultConnectionListenerFailureHandler.java Mon Nov 6 21:52:15 2006 @@ -0,0 +1,102 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * Copyright 1999-2006 The Apache Software Foundation + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.axis2.transport.http.server; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** Default hander for failures in connection listener IOProcessors. + * Supports configuration of number retries, delay per retry, and uptime interval considered a success (resets number retries to zero). + */ +public class DefaultConnectionListenerFailureHandler implements ConnectionListenerFailureHandler { + + private static final Log LOG = LogFactory.getLog(DefaultConnectionListenerFailureHandler.class); + + protected int retryDelay; + protected int successInterval; + protected int maxRetries; + + private long lastFailure; + private long lastFirstFailure; + private int numRetries; + + /** Create a new DefaultConnectionListenerFailureHandler with default settings. + * retryDelay is 1 second, successInterval is 60 seconds, maxRetries is 10 + */ + public DefaultConnectionListenerFailureHandler() { + this(1000, 60000, 10); + } + + /** Create a new DefaultConnectionListenerFailureHandler + * @param retryDelay millis to wait before retrying + * @param successInterval millis after which an initial or retry attempt will be deemed a success, resetting retry count to 0 + * @param maxRetries maximum number of retries allowed without a success, after which the listener will terminate + */ + public DefaultConnectionListenerFailureHandler(int retryDelay, int successInterval, int maxRetries) { + this.retryDelay = retryDelay; + this.successInterval = successInterval; + this.maxRetries = maxRetries; + this.lastFailure = this.lastFirstFailure = Long.MIN_VALUE; + this.numRetries = 0; + } + + /** Default behavior is to log a warning and attempt retry per constructor config, eventually failing with a logged error and notification. + * May subclass and override this method to change the behavior. + */ + public boolean failed(IOProcessor connectionListener, Throwable cause) { + long now = System.currentTimeMillis(); + if (now > lastFailure+successInterval) { + numRetries = 0; + lastFirstFailure = now; + } + lastFailure = now; + if (numRetries >= maxRetries) { + notifyAbnormalTermination( + connectionListener, + "Terminating connection listener " + connectionListener + " after " + numRetries + "retries in " + (now-lastFirstFailure)/1000 + " seconds.", + cause); + return false; + } else { + numRetries++; + if (LOG.isWarnEnabled()) + LOG.warn("Attempt number " + numRetries + " of " + maxRetries + " to reestalish connection listener " + connectionListener + " due to failure ", + cause); + return true; + } + } + + /** Default bevarior is to log the error. + * May subclass and override this method to change behavior. + */ + public void notifyAbnormalTermination(IOProcessor connectionListener, String message, Throwable cause) { + LOG.error(message, cause); + } + +} --------------------------------------------------------------------- To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org For additional commands, e-mail: axis-cvs-help@ws.apache.org