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/03/29 20:27:22 UTC
incubator-tinkerpop git commit: Minor adjustment to allow LifeCycle
override of scriptEvaluationTimeout
Repository: incubator-tinkerpop
Updated Branches:
refs/heads/tp31 3cb9bfcf9 -> 733a3320a
Minor adjustment to allow LifeCycle override of scriptEvaluationTimeout
This opens up the option to pass in a per-request scriptEvaluationTimeout in Gremlin Server. That might be useful for mixed load queries over OLAP/OLTP. CTR.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/733a3320
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/733a3320
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/733a3320
Branch: refs/heads/tp31
Commit: 733a3320aec5e04bdcca1e1f0f1e8e28e6a04539
Parents: 3cb9bfc
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Mar 29 14:25:42 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Mar 29 14:25:42 2016 -0400
----------------------------------------------------------------------
.../gremlin/groovy/engine/GremlinExecutor.java | 27 +++++++++++++++---
.../groovy/engine/GremlinExecutorTest.java | 29 ++++++++++++++++++++
2 files changed, 52 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/733a3320/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
index edd421d..5ef8667 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
@@ -248,6 +248,9 @@ public class GremlinExecutor implements AutoCloseable {
bindings.putAll(globalBindings);
bindings.putAll(boundVars);
+ // override the timeout if the lifecycle has a value assigned
+ final long seto = lifeCycle.scriptEvaluationTimeoutOverride.orElse(scriptEvaluationTimeout);
+
final CompletableFuture<Object> evaluationFuture = new CompletableFuture<>();
final FutureTask<Void> f = new FutureTask<>(() -> {
try {
@@ -282,7 +285,7 @@ public class GremlinExecutor implements AutoCloseable {
// check for that situation and convert to TimeoutException
if (root instanceof InterruptedException)
evaluationFuture.completeExceptionally(new TimeoutException(
- String.format("Script evaluation exceeded the configured 'scriptEvaluationTimeout' threshold of %s ms for request [%s]: %s", scriptEvaluationTimeout, script, root.getMessage())));
+ String.format("Script evaluation exceeded the configured 'scriptEvaluationTimeout' threshold of %s ms for request [%s]: %s", seto, script, root.getMessage())));
else {
lifeCycle.getAfterFailure().orElse(afterFailure).accept(bindings, root);
evaluationFuture.completeExceptionally(root);
@@ -294,7 +297,7 @@ public class GremlinExecutor implements AutoCloseable {
executorService.execute(f);
- if (scriptEvaluationTimeout > 0) {
+ if (seto > 0) {
// Schedule a timeout in the thread pool for future execution
final ScheduledFuture<?> sf = scheduledExecutorService.schedule(() -> {
logger.warn("Timing out script - {} - in thread [{}]", script, Thread.currentThread().getName());
@@ -302,7 +305,7 @@ public class GremlinExecutor implements AutoCloseable {
lifeCycle.getAfterTimeout().orElse(afterTimeout).accept(bindings);
f.cancel(true);
}
- }, scriptEvaluationTimeout, TimeUnit.MILLISECONDS);
+ }, seto, TimeUnit.MILLISECONDS);
// Cancel the scheduled timeout if the eval future is complete or the script evaluation failed
// with exception
@@ -539,7 +542,7 @@ public class GremlinExecutor implements AutoCloseable {
}
/**
- * Replaces any settings provided by {@link #engineSettings(java.util.Map)}.
+ * Replaces any settings provided.
*/
public Builder engineSettings(final Map<String, EngineSettings> settings) {
this.settings = settings;
@@ -685,6 +688,7 @@ public class GremlinExecutor implements AutoCloseable {
private final Optional<Consumer<Bindings>> afterSuccess;
private final Optional<Consumer<Bindings>> afterTimeout;
private final Optional<BiConsumer<Bindings, Throwable>> afterFailure;
+ private final Optional<Long> scriptEvaluationTimeoutOverride;
private LifeCycle(final Builder builder) {
beforeEval = Optional.ofNullable(builder.beforeEval);
@@ -693,6 +697,11 @@ public class GremlinExecutor implements AutoCloseable {
afterSuccess = Optional.ofNullable(builder.afterSuccess);
afterTimeout = Optional.ofNullable(builder.afterTimeout);
afterFailure = Optional.ofNullable(builder.afterFailure);
+ scriptEvaluationTimeoutOverride = Optional.ofNullable(builder.scriptEvaluationTimeoutOverride);
+ }
+
+ public Optional<Long> getScriptEvaluationTimeoutOverride() {
+ return scriptEvaluationTimeoutOverride;
}
public Optional<Consumer<Bindings>> getBeforeEval() {
@@ -730,6 +739,7 @@ public class GremlinExecutor implements AutoCloseable {
private Consumer<Bindings> afterSuccess = null;
private Consumer<Bindings> afterTimeout = null;
private BiConsumer<Bindings, Throwable> afterFailure = null;
+ private Long scriptEvaluationTimeoutOverride = null;
/**
* Specifies the function to execute prior to the script being evaluated. This function can also be
@@ -786,6 +796,15 @@ public class GremlinExecutor implements AutoCloseable {
return this;
}
+ /**
+ * An override to the global {@code scriptEvaluationTimeout} setting on the script engine. If this value
+ * is set to {@code null} (the default) it will use the global setting.
+ */
+ public Builder scriptEvaluationTimeoutOverride(final Long scriptEvaluationTimeoutOverride) {
+ this.scriptEvaluationTimeoutOverride = scriptEvaluationTimeoutOverride;
+ return this;
+ }
+
public LifeCycle create() {
return new LifeCycle(this);
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/733a3320/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
index 22c1699..387f0a1 100644
--- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
+++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
@@ -271,6 +271,35 @@ public class GremlinExecutorTest {
}
@Test
+ public void shouldTimeoutSleepingScriptViaOverrideOnLifeCycle() throws Exception {
+ final AtomicBoolean successCalled = new AtomicBoolean(false);
+ final AtomicBoolean failureCalled = new AtomicBoolean(false);
+
+ final CountDownLatch timeOutCount = new CountDownLatch(1);
+
+ final GremlinExecutor gremlinExecutor = GremlinExecutor.build()
+ .scriptEvaluationTimeout(10000)
+ .afterFailure((b, e) -> failureCalled.set(true))
+ .afterSuccess((b) -> successCalled.set(true))
+ .afterTimeout((b) -> timeOutCount.countDown()).create();
+ try {
+ final GremlinExecutor.LifeCycle lifeCycle = GremlinExecutor.LifeCycle.build()
+ .scriptEvaluationTimeoutOverride(250L).create();
+ gremlinExecutor.eval("Thread.sleep(1000);10", "gremlin-groovy", new SimpleBindings(), lifeCycle).get();
+ fail("This script should have timed out with an exception");
+ } catch (Exception ex) {
+ assertEquals(TimeoutException.class, ex.getCause().getClass());
+ }
+
+ assertTrue(timeOutCount.await(2000, TimeUnit.MILLISECONDS));
+
+ assertFalse(successCalled.get());
+ assertFalse(failureCalled.get());
+ assertEquals(0, timeOutCount.getCount());
+ gremlinExecutor.close();
+ }
+
+ @Test
public void shouldOverrideBeforeEval() throws Exception {
final AtomicInteger called = new AtomicInteger(0);
final GremlinExecutor gremlinExecutor = GremlinExecutor.build().beforeEval(b -> called.set(1)).create();