org.mule.providers.SimpleRetryConnectionStrategy Maven / Gradle / Ivy
The newest version!
/**
* Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
*
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
/**
* Copyright 2012 Bull S.A.S.
*
* 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.
*/
// Jasmine: patch for not outputting stack traces when reconnecting to a JMS resource.
// See: http://jira.jasmine.objectweb.org/browse/MONITORING-165
package org.mule.providers;
import org.mule.config.ExceptionHelper;
import org.mule.config.i18n.CoreMessages;
import org.mule.umo.provider.UMOConnectable;
import org.mule.util.ObjectUtils;
import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicInteger;
/**
* A simple connection retry strategy where the a connection will be attempted X
* number of retryCount every Y milliseconds. The retryCount and frequency
* properties can be set to customise the behaviour.
*/
public class SimpleRetryConnectionStrategy extends AbstractConnectionStrategy
{
public static final int DEFAULT_FREQUENCY = 2000;
public static final int DEFAULT_RETRY_COUNT = 2;
public static final int RETRY_COUNT_FOREVER = -1;
protected static class RetryCounter extends ThreadLocal
{
public int countRetry()
{
return ((AtomicInteger) get()).incrementAndGet();
}
public void reset()
{
((AtomicInteger) get()).set(0);
}
public AtomicInteger current()
{
return (AtomicInteger) get();
}
// @Override
protected Object initialValue()
{
return new AtomicInteger(0);
}
}
protected static final RetryCounter retryCounter = new RetryCounter();
protected static final ThreadLocal called = new ThreadLocal();
private volatile int retryCount = DEFAULT_RETRY_COUNT;
private volatile long frequency = DEFAULT_FREQUENCY;
protected void doConnect(UMOConnectable connectable) throws FatalConnectException
{
while (true)
{
final Boolean recursiveCallDetected = (Boolean) ObjectUtils.defaultIfNull(called.get(), Boolean.FALSE);
if (!recursiveCallDetected.booleanValue())
{
retryCounter.countRetry();
}
called.set(Boolean.TRUE);
try
{
connectable.connect();
if (logger.isDebugEnabled())
{
logger.debug("Successfully connected to " + getDescription(connectable));
}
break;
}
catch (InterruptedException ie)
{
// If we were interrupted it's probably because the server is
// shutting down
throw new FatalConnectException(
// TODO it's not only endpoint that is reconnected, connectors too
CoreMessages.reconnectStrategyFailed(this.getClass(),
this.getDescription(connectable)), ie, connectable);
}
catch (Exception e)
{
if (e instanceof FatalConnectException)
{
// rethrow
throw (FatalConnectException) e;
}
if (retryCount != RETRY_COUNT_FOREVER && retryCounter.current().get() >= retryCount)
{
throw new FatalConnectException(
// TODO it's not only endpoint that is reconnected, connectors too
CoreMessages.reconnectStrategyFailed(this.getClass(),
this.getDescription(connectable)), e, connectable);
}
if (logger.isInfoEnabled())
{
StringBuffer msg = new StringBuffer(512);
msg.append("Failed to connect/reconnect: ");
msg.append(getDescription(connectable));
msg.append("Waiting for ");
msg.append(frequency);
msg.append("ms before reconnecting. Failed attempt ");
msg.append(retryCounter.current().get());
msg.append(" of ");
msg.append((retryCount != RETRY_COUNT_FOREVER ? String.valueOf(retryCount) : "unlimited"));
logger.info(msg.toString());
}
try
{
Thread.sleep(frequency);
}
catch (InterruptedException e1)
{
throw new FatalConnectException(
// TODO it's not only endpoint that is reconnected, connectors too
CoreMessages.reconnectStrategyFailed(this.getClass(),
this.getDescription(connectable)), e, connectable);
}
}
finally
{
called.set(Boolean.FALSE);
}
}
}
/**
* Resets any state stored in the retry strategy
*/
public synchronized void resetState()
{
retryCounter.reset();
}
public int getRetryCount()
{
return retryCount;
}
/**
* How many times to retry. Set to -1 to retry forever.
* @param retryCount number of retries
*/
public void setRetryCount(int retryCount)
{
this.retryCount = retryCount;
}
public long getFrequency()
{
return frequency;
}
public void setFrequency(long frequency)
{
this.frequency = frequency;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy