You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by Sanjiva Weerawarana <sa...@opensource.lk> on 2006/11/07 11:31:59 UTC
Re: 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
Hi Chuck,
Is there a testcase in this commit too? I'm a bit worried since its late
in the release cycle. Sorry if I missed discussion on the list.
Sanjiva.
On Tue, 2006-11-07 at 05:52 +0000, chuckw@apache.org wrote:
> 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
> + * <http://www.apache.org/>.
> + *
> + */
> +
> +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
> + * <http://www.apache.org/>.
> + *
> + */
> +
> +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
>
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org