You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2016/01/09 18:26:13 UTC

incubator-tinkerpop git commit: Used a independent loop control for result interation.

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1035 0e2700508 -> 58cd80672


Used a independent loop control for result interation.

This solves a problem where a graph could automatically open a new transaction on the same request.  In the result iteration loop, a commit gets called if there are no results left, when the loop traverse back to the top of the while() to exit, it does a final check to Traversal.hasNext().  On some graphs, automatic transaction handling could open a new transaction there. subtle - oh so subtle.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/58cd8067
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/58cd8067
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/58cd8067

Branch: refs/heads/TINKERPOP-1035
Commit: 58cd80672c036f5b4eeab54e007627ca12c47800
Parents: 0e27005
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Sat Jan 9 12:23:20 2016 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Sat Jan 9 12:23:20 2016 -0500

----------------------------------------------------------------------
 .../gremlin/server/op/AbstractEvalOpProcessor.java   | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/58cd8067/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
index 171edfb..4d85822 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
@@ -262,7 +262,13 @@ public abstract class AbstractEvalOpProcessor implements OpProcessor {
         final int resultIterationBatchSize = (Integer) msg.optionalArgs(Tokens.ARGS_BATCH_SIZE)
                 .orElse(settings.resultIterationBatchSize);
         List<Object> aggregate = new ArrayList<>(resultIterationBatchSize);
-        while (toIterate.hasNext()) {
+
+        // use an external control to manage the loop as opposed to just checking hasNext() in the while.  this
+        // prevent situations where auto transactions create a new transaction after calls to commit() withing
+        // the loop on calls to hasNext().
+        boolean hasMore = toIterate.hasNext();
+
+        while (hasMore) {
             if (Thread.interrupted()) throw new InterruptedException();
 
             // have to check the aggregate size because it is possible that the channel is not writeable (below)
@@ -291,7 +297,12 @@ public abstract class AbstractEvalOpProcessor implements OpProcessor {
                         // local errors will get rolledback below because the exceptions aren't thrown in those cases to be
                         // caught by the GremlinExecutor for global rollback logic. this only needs to be committed if
                         // there are no more items to iterate and serialization is complete
-                        if (manageTransactions && !toIterate.hasNext()) attemptCommit(msg, context.getGraphManager(), settings.strictTransactionManagement);
+                        if (manageTransactions) attemptCommit(msg, context.getGraphManager(), settings.strictTransactionManagement);
+
+                        // exit the result iteration loop as there are no more results left.  using this external control
+                        // because of the above commit.  some graphs may open a new transaction on the call to
+                        // hasNext()
+                        hasMore = false;
                     }
 
                     // the flush is called after the commit has potentially occurred.  in this way, if a commit was