From 18080460611df28829f0dca1badb823612bf6531 Mon Sep 17 00:00:00 2001 From: jbertram Date: Tue, 11 Mar 2014 13:28:05 -0500 Subject: [PATCH] Simple retry mechanism to cope with a temporarily unavailable endpoint Motivation: Use simple retry mechanism when try to connect to peer so a slow-startup will not produce an error Modification: Add new Servlet params which allow to configure retry count and wait time. Default behaviour is the same as before Result: It is now possible to configure retry when the peer is not up yet and the Servlet is init. --- .../socket/http/HttpTunnelingServlet.java | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jboss/netty/channel/socket/http/HttpTunnelingServlet.java b/src/main/java/org/jboss/netty/channel/socket/http/HttpTunnelingServlet.java index 757a50d95b..24be628eef 100644 --- a/src/main/java/org/jboss/netty/channel/socket/http/HttpTunnelingServlet.java +++ b/src/main/java/org/jboss/netty/channel/socket/http/HttpTunnelingServlet.java @@ -63,11 +63,15 @@ public class HttpTunnelingServlet extends HttpServlet { private static final long serialVersionUID = 4259910275899756070L; private static final String ENDPOINT = "endpoint"; + private static final String CONNECT_ATTEMPTS = "connectAttempts"; + private static final String RETRY_DELAY = "retryDelay"; static final InternalLogger logger = InternalLoggerFactory.getInstance(HttpTunnelingServlet.class); private volatile SocketAddress remoteAddress; private volatile ChannelFactory channelFactory; + private volatile long connectAttempts = 1; + private volatile long retryDelay; @Override public void init() throws ServletException { @@ -93,6 +97,34 @@ public class HttpTunnelingServlet extends HttpServlet { throw new ServletException("Failed to create a channel factory.", e); } + String temp = config.getInitParameter(CONNECT_ATTEMPTS); + if (temp != null) { + try { + connectAttempts = Long.parseLong(temp); + } catch (NumberFormatException e) { + throw new ServletException( + "init-param '" + CONNECT_ATTEMPTS + "' is not a valid number. Actual value: " + temp); + } + if (connectAttempts < 1) { + throw new ServletException( + "init-param '" + CONNECT_ATTEMPTS + "' must be >= 1. Actual value: " + connectAttempts); + } + } + + temp = config.getInitParameter(RETRY_DELAY); + if (temp != null) { + try { + retryDelay = Long.parseLong(temp); + } catch (NumberFormatException e) { + throw new ServletException( + "init-param '" + RETRY_DELAY + "' is not a valid number. Actual value: " + temp); + } + if (retryDelay < 0) { + throw new ServletException( + "init-param '" + RETRY_DELAY + "' must be >= 0. Actual value: " + retryDelay); + } + } + // Stuff for testing purpose //ServerBootstrap b = new ServerBootstrap(new DefaultLocalServerChannelFactory()); //b.getPipeline().addLast("logger", new LoggingHandler(getClass(), InternalLogLevel.INFO, true)); @@ -147,7 +179,23 @@ public class HttpTunnelingServlet extends HttpServlet { pipeline.addLast("handler", handler); Channel channel = channelFactory.newChannel(pipeline); - ChannelFuture future = channel.connect(remoteAddress).awaitUninterruptibly(); + int tries = 0; + ChannelFuture future = null; + + while (tries < connectAttempts) { + future = channel.connect(remoteAddress).awaitUninterruptibly(); + if (!future.isSuccess()) { + tries++; + try { + Thread.sleep(retryDelay); + } catch (InterruptedException e) { + // ignore + } + } else { + break; + } + } + if (!future.isSuccess()) { Throwable cause = future.getCause(); logger.warn("Endpoint unavailable: " + cause.getMessage(), cause);