com.tinkerpop.blueprints.util.TransactionRetryStrategy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of blueprints-core Show documentation
Show all versions of blueprints-core Show documentation
Core interfaces and utilities for Blueprints
The newest version!
package com.tinkerpop.blueprints.util;
import com.tinkerpop.blueprints.TransactionalGraph;
import java.util.HashSet;
import java.util.Set;
/**
* The strategy for executing a transaction.
*
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
public interface TransactionRetryStrategy {
/**
* Executes the TransactionWork with a give strategy.
*
* @param graph The TransactionalGraph to mutate.
* @param work The work to do on the Graph.
* @return The return value from TransactionWork.
*/
public T execute(TransactionalGraph graph, TransactionWork work);
/**
* Executes the work committing if possible and rolling back on failure. On failure, an exception is reported.
*/
public static class OneAndDone implements TransactionRetryStrategy {
public T execute(final TransactionalGraph graph, final TransactionWork work) {
T returnValue;
try {
returnValue = work.execute(graph);
graph.commit();
} catch (Exception e) {
graph.rollback();
throw new RuntimeException(e);
}
return returnValue;
}
}
/**
* Executes the work committing if possible and rolling back on failure. On failure no exception is reported.
*/
public static class FireAndForget implements TransactionRetryStrategy {
public T execute(final TransactionalGraph graph, final TransactionWork work) {
T returnValue = null;
try {
returnValue = work.execute(graph);
graph.commit();
} catch (Exception e) {
graph.rollback();
}
return returnValue;
}
}
/**
* Executes the work with a number of retries and with a number of milliseconds delay between each try.
*/
public static class DelayedRetry extends AbstractRetryStrategy {
public static final long DEFAULT_DELAY_MS = 20;
private final long delayBetweenRetry;
public DelayedRetry() {
this(DEFAULT_TRIES, DEFAULT_DELAY_MS);
}
public DelayedRetry(final int tries, final long delayBetweenRetry) {
this(tries, delayBetweenRetry, new HashSet());
}
public DelayedRetry(final int tries, final long delayBetweenRetry, final Set exceptionsToRetryOn) {
super(tries, exceptionsToRetryOn);
this.delayBetweenRetry = delayBetweenRetry;
}
@Override
long getDelay(final int retryCount) {
return this.delayBetweenRetry;
}
}
/**
* Executes the work with a number of retries and with a exponentially increasing number of milliseconds
* between each retry.
*/
public static class ExponentialBackoff extends AbstractRetryStrategy {
public static final long DEFAULT_DELAY_MS = 20;
private final long initialDelay;
public ExponentialBackoff() {
this(DEFAULT_TRIES, DEFAULT_DELAY_MS);
}
public ExponentialBackoff(final int tries, final long initialDelay) {
this(tries, initialDelay, new HashSet());
}
public ExponentialBackoff(final int tries, final long initialDelay, final Set exceptionsToRetryOn) {
super(tries, exceptionsToRetryOn);
this.initialDelay = initialDelay;
}
@Override
long getDelay(final int retryCount) {
return (long) (initialDelay * Math.pow(2, retryCount));
}
}
/**
* Base class for strategy that require a retry.
*/
public static abstract class AbstractRetryStrategy implements TransactionRetryStrategy {
public static final int DEFAULT_TRIES = 8;
protected final int tries;
protected final Set exceptionsToRetryOn;
public AbstractRetryStrategy() {
this(DEFAULT_TRIES, new HashSet());
}
public AbstractRetryStrategy(final int tries, final Set exceptionsToRetryOn) {
this.tries = tries;
this.exceptionsToRetryOn = exceptionsToRetryOn;
}
abstract long getDelay(int retryCount);
public T execute(final TransactionalGraph graph, final TransactionWork work) {
T returnValue;
// this is the default exception...it may get reassgined during retries
Exception previousException = new RuntimeException("Exception initialized when trying commit.");
// try to commit a few times
for (int ix = 0; ix < tries; ix++) {
// increase time after each failed attempt though there is no delay on the first try
if (ix > 0)
try { Thread.sleep(getDelay(ix)); } catch (InterruptedException ie) { }
try {
returnValue = work.execute(graph);
graph.commit();
// need to exit the function here so that retries don't happen
return returnValue;
} catch (Exception ex) {
graph.rollback();
// retry if this is an allowed exception otherwise, just throw and go
boolean retry = false;
if (this.exceptionsToRetryOn.size() == 0)
retry = true;
else {
for (Class exceptionToRetryOn : this.exceptionsToRetryOn) {
if (ex.getClass().equals(exceptionToRetryOn)) {
retry = true;
break;
}
}
}
if (!retry) {
throw new RuntimeException(ex);
}
previousException = ex;
}
}
// the exception just won't go away after all the retries
throw new RuntimeException(previousException);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy