TINKERPOP-741 Removed deprecated transaction retry methods
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/80822ee5 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/80822ee5 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/80822ee5 Branch: refs/heads/TINKERPOP-1698 Commit: 80822ee52c7eb500e38a444d44f98b5469c496e6 Parents: 21102e4 Author: Stephen Mallette <[email protected]> Authored: Mon Jun 19 12:15:33 2017 -0400 Committer: Stephen Mallette <[email protected]> Committed: Mon Jun 19 12:15:33 2017 -0400 ---------------------------------------------------------------------- CHANGELOG.asciidoc | 1 + .../gremlin/structure/Transaction.java | 216 ----------------- .../structure/util/AbstractTransaction.java | 9 - .../gremlin/structure/TransactionTest.java | 242 +------------------ 4 files changed, 11 insertions(+), 457 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/80822ee5/CHANGELOG.asciidoc ---------------------------------------------------------------------- diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index af56ed1..ddf3a83 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -32,6 +32,7 @@ TinkerPop 3.3.0 (Release Date: NOT OFFICIALLY RELEASED YET) * Added "attachment requisite" `VertexProperty.element()` and `Property.element()` data in GraphSON serialization. * GraphSON 3.0 is now the default serialization format in TinkerGraph and Gremlin Server. * Established the GraphSON 3.0 format. +* Removed previously deprecated `Transaction.submit(Function)`. * Removed previously deprecated `OpSelectorHandler.errorMeter` and `AbstractEvalOpProcessor.errorMeter` fields. * Removed previously deprecated `AbstractEvalOpProcessor.validBindingName` field. * Removed previously deprecated `SimpleAuthenticator.CONFIG_CREDENTIALS_LOCATION` field. http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/80822ee5/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Transaction.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Transaction.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Transaction.java index ff4232d..8d73bf6 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Transaction.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Transaction.java @@ -61,14 +61,6 @@ public interface Transaction extends AutoCloseable { public void rollback(); /** - * Submit a unit of work that represents a transaction returning a {@link Workload} that can be automatically - * retried in the event of failure. - * @deprecated As of release 3.2.6, not replaced. - */ - @Deprecated - public <R> Workload<R> submit(final Function<Graph, R> work); - - /** * Creates a transaction that can be executed across multiple threads. The {@link Graph} returned from this * method is not meant to represent some form of child transaction that can be committed from this object. * A threaded transaction is a {@link Graph} instance that has a transaction context that enables multiple @@ -221,212 +213,4 @@ public interface Transaction extends AutoCloseable { } } } - - /** - * A {@link Workload} represents a unit of work constructed by the {@link Workload#submit(Function)} method on - * the {@link Transaction} interface. The unit of work is a {@link Function} typically containing mutations to - * the {@link Graph}. The {@link Workload} is responsible for executing the unit of work in the context of a - * retry strategy, such that a failed unit of work is rolled back and executed again until retries are exhausted - * or the unit of work succeeds with a commit operation. - * - * @param <R> The type of the result from the unit of work. - * @deprecated As of release 3.2.6, not replaced. - */ - @Deprecated - public static class Workload<R> { - public static final long DEFAULT_DELAY_MS = 20; - public static final int DEFAULT_TRIES = 8; - - private final Function<Graph, R> workToDo; - private final Graph g; - - /** - * Creates a new {@link Workload} that will be tried to be executed within a transaction. - * - * @param g The {@link Graph} instance on which the work will be performed. - * @param work The work to be executed on the Graph instance which will optionally return a value. - */ - public Workload(final Graph g, final Function<Graph, R> work) { - this.g = g; - this.workToDo = work; - } - - /** - * Try to execute a {@link Workload} with a mapper retry strategy. - * - * @param retryStrategy The first argument to this function is the Graph instance and the second is - * the encapsulated work to be performed. The function should ultimately return the - * result of the encapsulated work function. - * @return The result of the encapsulated work. - */ - public R attempt(final BiFunction<Graph, Function<Graph, R>, R> retryStrategy) { - return retryStrategy.apply(g, workToDo); - } - - /** - * Executes the {@link Workload} committing if possible and rolling back on failure. On failure, an exception - * is reported. - */ - public R oneAndDone() { - return attempt((g, w) -> { - try { - R result = w.apply(g); - g.tx().commit(); - - return result; - } catch (Throwable t) { - g.tx().rollback(); - throw new RuntimeException(t); - } - }); - } - - /** - * Executes the {@link Workload} committing if possible and rolling back on failure. On failure no exception - * is reported. - */ - public R fireAndForget() { - return attempt((g, w) -> { - R result = null; - try { - result = w.apply(g); - g.tx().commit(); - } catch (Throwable t) { - g.tx().rollback(); - } - - return result; - }); - } - - /** - * Executes the {@link Workload} with the default number of retries and with the default number of - * milliseconds delay between each try. - */ - public R retry() { - return retry(DEFAULT_TRIES); - } - - /** - * Executes the {@link Workload} with a number of retries and with the default number of milliseconds delay - * between each try. - */ - public R retry(final int tries) { - return retry(tries, DEFAULT_DELAY_MS); - } - - /** - * Executes the {@link Workload} with a number of retries and with a number of milliseconds delay between - * each try. - */ - public R retry(final int tries, final long delay) { - return retry(tries, delay, Collections.emptySet()); - } - - /** - * Executes the {@link Workload} with a number of retries and with a number of milliseconds delay between each - * try and will only retry on the set of supplied exceptions. Exceptions outside of that set will generate a - * RuntimeException and immediately fail. - */ - public R retry(final int tries, final long delay, final Set<Class> exceptionsToRetryOn) { - return attempt(retry(tries, exceptionsToRetryOn, i -> delay)); - } - - /** - * Executes the {@link Workload} with the default number of retries and with a exponentially increasing - * number of milliseconds between each retry using the default retry delay. - */ - public R exponentialBackoff() { - return exponentialBackoff(DEFAULT_TRIES); - } - - /** - * Executes the {@link Workload} with a number of retries and with a exponentially increasing number of - * milliseconds between each retry using the default retry delay. - */ - public R exponentialBackoff(final int tries) { - return exponentialBackoff(tries, DEFAULT_DELAY_MS); - } - - /** - * Executes the {@link Workload} with a number of retries and with a exponentially increasing number of - * milliseconds between each retry. - */ - public R exponentialBackoff(final int tries, final long initialDelay) { - return exponentialBackoff(tries, initialDelay, Collections.emptySet()); - } - - /** - * Executes the {@link Workload} with a number of retries and with a exponentially increasing number of - * milliseconds between each retry. It will only retry on the set of supplied exceptions. Exceptions outside - * of that set will generate a {@link RuntimeException} and immediately fail. - */ - public R exponentialBackoff(final int tries, final long initialDelay, final Set<Class> exceptionsToRetryOn) { - return attempt(retry(tries, exceptionsToRetryOn, retryCount -> (long) (initialDelay * Math.pow(2, retryCount)))); - } - - /** - * Creates a generic retry function to be passed to the {@link Workload#attempt(java.util.function.BiFunction)} - * method. - */ - private static <R> BiFunction<Graph, Function<Graph, R>, R> retry(final int tries, - final Set<Class> exceptionsToRetryOn, - final Function<Integer, Long> delay) { - return (g, w) -> { - R 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(delay.apply(ix)); - } catch (InterruptedException ignored) { - } - - try { - // ensure that a transaction is open for this try. even if there was an open transaction - // from the first try it would be rolled back on failure and unless automatic transactions - // are used, the transaction would be closed on the next retry. - if (!g.tx().isOpen()) g.tx().open(); - - returnValue = w.apply(g); - g.tx().commit(); - - // need to exit the function here so that retries don't happen - return returnValue; - } catch (Exception ex) { - g.tx().rollback(); - - // retry if this is an allowed exception otherwise, just throw and go - boolean retry = false; - if (exceptionsToRetryOn.size() == 0) - retry = true; - else { - for (Class exceptionToRetryOn : 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); - }; - } - } - } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/80822ee5/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractTransaction.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractTransaction.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractTransaction.java index 35f484e..fec7df7 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractTransaction.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractTransaction.java @@ -125,15 +125,6 @@ public abstract class AbstractTransaction implements Transaction { /** * {@inheritDoc} - * @deprecated As of release 3.2.6, not replaced. - */ - @Override - @Deprecated - public <R> Workload<R> submit(final Function<Graph, R> work) { - return new Workload<>(g, work); - } - /** - * {@inheritDoc} */ @Override public <G extends Graph> G createThreadedTx() { http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/80822ee5/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/TransactionTest.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/TransactionTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/TransactionTest.java index 4dbbc5f..ad08132 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/TransactionTest.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/TransactionTest.java @@ -22,15 +22,12 @@ import org.apache.tinkerpop.gremlin.AbstractGremlinTest; import org.apache.tinkerpop.gremlin.ExceptionCoverage; import org.apache.tinkerpop.gremlin.FeatureRequirement; import org.apache.tinkerpop.gremlin.FeatureRequirementSet; -import org.apache.tinkerpop.gremlin.util.function.FunctionUtils; import org.apache.commons.configuration.Configuration; import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils; import org.junit.Test; -import java.util.HashSet; import java.util.NoSuchElementException; import java.util.Random; -import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -44,7 +41,9 @@ import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexProper import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexPropertyFeatures.FEATURE_INTEGER_VALUES; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsInstanceOf.instanceOf; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; /** * @author Stephen Mallette (http://stephen.genoprime.com) @@ -407,7 +406,7 @@ public class TransactionTest extends AbstractGremlinTest { t.join(); // this was committed - assertTrue(graph.vertices(vid.get().id()).hasNext()); + assertThat(graph.vertices(vid.get().id()).hasNext(), is(true)); try { // this was not @@ -571,7 +570,7 @@ public class TransactionTest extends AbstractGremlinTest { threadTxStarter.join(); threadTryCommitTx.join(); - assertTrue(noVerticesInFirstThread.get()); + assertThat(noVerticesInFirstThread.get(), is(true)); assertVertexEdgeCounts(graph, 0, 0); } @@ -653,224 +652,6 @@ public class TransactionTest extends AbstractGremlinTest { } @Test - @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) - @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) - public void shouldSupportTransactionFireAndForget() { - // first fail the tx - g.tx().submit(FunctionUtils.wrapFunction(grx -> { - grx.addVertex(); - throw new Exception("fail"); - })).fireAndForget(); - assertVertexEdgeCounts(graph, 0, 0); - - // this tx will work - g.tx().submit(grx -> graph.addVertex()).fireAndForget(); - assertVertexEdgeCounts(graph, 1, 0); - - // make sure a commit happened and a new tx started - g.tx().rollback(); - assertVertexEdgeCounts(graph, 1, 0); - } - - @Test - @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) - @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) - public void shouldSupportTransactionOneAndDone() { - // first fail the tx - try { - g.tx().submit(FunctionUtils.wrapFunction(grx -> { - grx.addVertex(); - throw new Exception("fail"); - })).oneAndDone(); - } catch (Exception ex) { - assertEquals("fail", ex.getCause().getCause().getMessage()); - } - - assertVertexEdgeCounts(graph, 0, 0); - - // this tx will work - g.tx().submit(grx -> graph.addVertex()).oneAndDone(); - assertVertexEdgeCounts(graph, 1, 0); - - // make sure a commit happened and a new tx started - g.tx().rollback(); - assertVertexEdgeCounts(graph, 1, 0); - } - - @Test - @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) - @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) - public void shouldSupportTransactionExponentialBackoff() { - - // first fail the tx - final AtomicInteger attempts = new AtomicInteger(0); - try { - g.tx().submit(FunctionUtils.wrapFunction(grx -> { - grx.addVertex(); - attempts.incrementAndGet(); - throw new Exception("fail"); - })).exponentialBackoff(); - } catch (Exception ex) { - assertEquals("fail", ex.getCause().getCause().getMessage()); - } - - assertEquals(Transaction.Workload.DEFAULT_TRIES, attempts.get()); - assertVertexEdgeCounts(graph, 0, 0); - - // this tx will work after several tries - final AtomicInteger tries = new AtomicInteger(0); - g.tx().submit(FunctionUtils.wrapFunction(grx -> { - final int tryNumber = tries.incrementAndGet(); - if (tryNumber == Transaction.Workload.DEFAULT_TRIES - 2) - return graph.addVertex(); - else - throw new Exception("fail"); - })).exponentialBackoff(); - - assertEquals(Transaction.Workload.DEFAULT_TRIES - 2, tries.get()); - assertVertexEdgeCounts(graph, 1, 0); - - // make sure a commit happened and a new tx started - g.tx().rollback(); - assertVertexEdgeCounts(graph, 1, 0); - } - - @Test - @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) - @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) - public void shouldSupportTransactionExponentialBackoffWithExceptionChecks() { - final Set<Class> exceptions = new HashSet<Class>() {{ - add(IllegalStateException.class); - }}; - - // first fail the tx - final AtomicInteger attempts = new AtomicInteger(0); - try { - g.tx().submit(FunctionUtils.wrapFunction(grx -> { - grx.addVertex(); - attempts.incrementAndGet(); - throw new Exception("fail"); - })).exponentialBackoff(Transaction.Workload.DEFAULT_TRIES, 20, exceptions); - } catch (Exception ex) { - assertEquals("fail", ex.getCause().getCause().getMessage()); - } - - assertEquals(1, attempts.get()); - assertVertexEdgeCounts(graph, 0, 0); - - // this tx will retry for specific tx and then fail after several tries - final AtomicInteger setOfTries = new AtomicInteger(0); - try { - g.tx().submit(FunctionUtils.wrapFunction(grx -> { - final int tryNumber = setOfTries.incrementAndGet(); - if (tryNumber == Transaction.Workload.DEFAULT_TRIES - 2) - throw new Exception("fail"); - else - throw new IllegalStateException("fail"); - })).exponentialBackoff(Transaction.Workload.DEFAULT_TRIES, 20, exceptions); - } catch (Exception ex) { - assertEquals("fail", ex.getCause().getCause().getMessage()); - } - - assertEquals(Transaction.Workload.DEFAULT_TRIES - 2, setOfTries.get()); - assertVertexEdgeCounts(graph, 0, 0); - - // this tx will work after several tries - final AtomicInteger tries = new AtomicInteger(0); - g.tx().submit(FunctionUtils.wrapFunction(grx -> { - final int tryNumber = tries.incrementAndGet(); - if (tryNumber == Transaction.Workload.DEFAULT_TRIES - 2) - return graph.addVertex(); - else - throw new IllegalStateException("fail"); - })).exponentialBackoff(Transaction.Workload.DEFAULT_TRIES, 20, exceptions); - - assertEquals(Transaction.Workload.DEFAULT_TRIES - 2, tries.get()); - assertVertexEdgeCounts(graph, 1, 0); - - // make sure a commit happened and a new tx started - g.tx().rollback(); - assertVertexEdgeCounts(graph, 1, 0); - } - - @Test - @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) - @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) - public void shouldSupportTransactionRetry() { - // first fail the tx - final AtomicInteger attempts = new AtomicInteger(0); - try { - g.tx().submit(FunctionUtils.wrapFunction(grx -> { - grx.addVertex(); - attempts.incrementAndGet(); - throw new Exception("fail"); - })).retry(); - } catch (Exception ex) { - assertEquals("fail", ex.getCause().getCause().getMessage()); - } - - assertEquals(Transaction.Workload.DEFAULT_TRIES, attempts.get()); - assertVertexEdgeCounts(graph, 0, 0); - - // this tx will work after several tries - final AtomicInteger tries = new AtomicInteger(0); - g.tx().submit(FunctionUtils.wrapFunction(grx -> { - final int tryNumber = tries.incrementAndGet(); - if (tryNumber == Transaction.Workload.DEFAULT_TRIES - 2) - return graph.addVertex(); - else - throw new Exception("fail"); - })).retry(); - - assertEquals(Transaction.Workload.DEFAULT_TRIES - 2, tries.get()); - assertVertexEdgeCounts(graph, 1, 0); - - // make sure a commit happened and a new tx started - g.tx().rollback(); - assertVertexEdgeCounts(graph, 1, 0); - } - - @Test - @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) - @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) - public void shouldSupportTransactionRetryWhenUsingManualTransactions() { - g.tx().onReadWrite(Transaction.READ_WRITE_BEHAVIOR.MANUAL); - - // first fail the tx - final AtomicInteger attempts = new AtomicInteger(0); - try { - g.tx().submit(FunctionUtils.wrapFunction(grx -> { - grx.addVertex(); - attempts.incrementAndGet(); - throw new Exception("fail"); - })).retry(); - } catch (Exception ex) { - assertEquals("fail", ex.getCause().getCause().getMessage()); - } - - assertEquals(Transaction.Workload.DEFAULT_TRIES, attempts.get()); - assertFalse(g.tx().isOpen()); - g.tx().open(); - assertVertexEdgeCounts(graph, 0, 0); - - // this tx will work after several tries - final AtomicInteger tries = new AtomicInteger(0); - g.tx().submit(FunctionUtils.wrapFunction(grx -> { - final int tryNumber = tries.incrementAndGet(); - if (tryNumber == Transaction.Workload.DEFAULT_TRIES - 2) - return graph.addVertex(); - else - throw new Exception("fail"); - })).retry(); - - assertEquals(Transaction.Workload.DEFAULT_TRIES - 2, tries.get()); - assertFalse(g.tx().isOpen()); - g.tx().open(); - assertVertexEdgeCounts(graph, 1, 0); - g.tx().rollback(); - } - - @Test @FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES) @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) @@ -1149,14 +930,11 @@ public class TransactionTest extends AbstractGremlinTest { manualThread.join(); autoThread.join(); - assertTrue( - "manualThread transaction readWrite should be MANUAL and should fail to commit the transaction", - commitFailed.get() - ); - assertTrue( - "autoThread transaction readWrite should be AUTO and should commit the transaction", - commitOccurred.get() - ); + assertThat("manualThread transaction readWrite should be MANUAL and should fail to commit the transaction", + commitFailed.get(), + is(true)); + assertThat("autoThread transaction readWrite should be AUTO and should commit the transaction", + commitOccurred.get(), is(true)); } @Test
