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/12 16:14:42 UTC
[7/9] incubator-tinkerpop git commit: Used a independent loop control
for result interation.
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/master
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