package com.tinkerpop.blueprints.util;
import com.tinkerpop.blueprints.TransactionalGraph;
import java.util.Set;
/**
* Creates a TransactionGraph "holder" which allows execution of a TransactionWork instance inside of a
* TransactionRetryStrategy implementation.
*
* @param <T> The return value of the work.
*/
public class TransactionRetryHelper<T> {
private final TransactionalGraph graph;
private final TransactionWork<T> work;
private TransactionRetryHelper(final Builder<T> builder) {
this.graph = builder.getGraph();
this.work = builder.getWork();
}
/**
* Executes the work committing if possible and rolling back on failure. On failure, not exception is reported.
*/
public T fireAndForget() {
return use(new TransactionRetryStrategy.FireAndForget<T>());
}
/**
* Executes the work committing if possible and rolling back on failure. On failure an exception is reported.
*/
public T oneAndDone() {
return use(new TransactionRetryStrategy.OneAndDone<T>());
}
/**
* Executes the work with a default number of retries with a default number of milliseconds delay between
* each try.
*/
public T retry() {
return use(new TransactionRetryStrategy.DelayedRetry<T>());
}
/**
* Executes the work with a specified number of retries with a default number of milliseconds delay between
* each try.
*/
public T retry(final int retries) {
return use(new TransactionRetryStrategy.DelayedRetry<T>(retries, TransactionRetryStrategy.DelayedRetry.DEFAULT_DELAY_MS));
}
/**
* Executes the work with a specified number of retries with a specified number of milliseconds delay between
* each try.
*/
public T retry(final int retries, final long delayBetweenRetries) {
return use(new TransactionRetryStrategy.DelayedRetry<T>(retries, delayBetweenRetries));
}
/**
* Executes the work with a specified number of retries with a specified number of milliseconds delay between
* each try.
*
* @param exceptionsToRetryOn For a retry to happen, it must be in this set of accepted exceptions. If an
* exception raises that is not in the set, then an error is immediately raised
* with no retry.
*/
public T retry(final int retries, final long delayBetweenRetries, final Set<Class> exceptionsToRetryOn ) {
return use(new TransactionRetryStrategy.DelayedRetry<T>(retries, delayBetweenRetries, exceptionsToRetryOn));
}
/**
* Executes the work with a default number of retries with a exponentially increasing number of milliseconds
* between each retry.
*/
public T exponentialBackoff() {
return use(new TransactionRetryStrategy.ExponentialBackoff<T>());
}
/**
* Executes the work with a specified number of retries with a exponentially increasing number of milliseconds
* between each retry.
*/
public T exponentialBackoff(final int retries) {
return use(new TransactionRetryStrategy.ExponentialBackoff<T>(
retries, TransactionRetryStrategy.ExponentialBackoff.DEFAULT_DELAY_MS));
}
/**
* Executes the work with a specified number of retries with a exponentially increasing number of milliseconds
* between each retry.
*/
public T exponentialBackoff(final int retries, final long initialDelay) {
return use(new TransactionRetryStrategy.ExponentialBackoff<T>(
retries, initialDelay));
}
/**
* Executes the work with a specified number of retries with a exponentially increasing number of milliseconds
* between each retry.
*
* @param exceptionsToRetryOn For a retry to happen, it must be in this set of accepted exceptions. If an
* exception raises that is not in the set, then an error is immediately raised
* with no retry.
*/
public T exponentialBackoff(final int retries, final long initialDelay, final Set<Class> exceptionsToRetryOn) {
return use(new TransactionRetryStrategy.ExponentialBackoff<T>(
retries, initialDelay, exceptionsToRetryOn));
}
/**
* Executes the work with a specified TransactionRetryStrategy.
*/
public T use(final TransactionRetryStrategy<T> strategy) {
return strategy.execute(this.graph, this.work);
}
/**
* Constructs a TransactionRetryStrategy.
*/
public static class Builder<T> {
private final TransactionalGraph graph;
private TransactionWork<T> work;
public Builder(final TransactionalGraph graph) {
this.graph = graph;
}
public Builder<T> perform(final TransactionWork<T> work) {
this.work = work;
return this;
}
public TransactionRetryHelper<T> build() {
return new TransactionRetryHelper<T>(this);
}
public TransactionalGraph getGraph() {
return graph;
}
public TransactionWork<T> getWork() {
return work;
}
}
}