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 2015/07/15 23:00:28 UTC

[13/31] incubator-tinkerpop git commit: Both TimedInterrupt and ThreadInterrupt compiler customizers are configurable.

Both TimedInterrupt and ThreadInterrupt compiler customizers are configurable.

In other words, they can be configured from yaml/properties into the GremlinExecutor which further unifies this model.  This design also allows for arbitrary and custom CompilerCustomizerProviders to be added.


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

Branch: refs/heads/tp30
Commit: 37796826dce643648b3148807fe82d13e9790190
Parents: 17ed3ce
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Jul 8 17:07:34 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Jul 8 17:07:34 2015 -0400

----------------------------------------------------------------------
 .../TimedInterruptCustomizerProvider.java       |  6 ++-
 .../gremlin/groovy/engine/ScriptEngines.java    | 36 ++++++++++++----
 .../groovy/engine/GremlinExecutorTest.java      | 44 +++++++++++++++++++-
 .../jsr223/GremlinGroovyScriptEngineTest.java   |  2 +
 4 files changed, 78 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/37796826/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/TimedInterruptCustomizerProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/TimedInterruptCustomizerProvider.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/TimedInterruptCustomizerProvider.java
index a8c8eb1..44dfe21 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/TimedInterruptCustomizerProvider.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/TimedInterruptCustomizerProvider.java
@@ -42,10 +42,14 @@ public class TimedInterruptCustomizerProvider implements CompilerCustomizerProvi
         this(DEFAULT_INTERRUPTION_TIMEOUT);
     }
 
-    public TimedInterruptCustomizerProvider(final long interruptionTimeout) {
+    public TimedInterruptCustomizerProvider(final Long interruptionTimeout) {
         this.interruptionTimeout = interruptionTimeout;
     }
 
+    public TimedInterruptCustomizerProvider(final Integer interruptionTimeout) {
+        this.interruptionTimeout = interruptionTimeout.longValue();
+    }
+
     @Override
     public CompilationCustomizer create() {
         final Map<String, Object> timedInterruptAnnotationParams = new HashMap<>();

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/37796826/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/ScriptEngines.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/ScriptEngines.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/ScriptEngines.java
index 24b9f58..ba7157e 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/ScriptEngines.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/ScriptEngines.java
@@ -41,8 +41,10 @@ import javax.script.ScriptException;
 import java.io.Closeable;
 import java.io.IOException;
 import java.io.Reader;
+import java.lang.reflect.Constructor;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -52,6 +54,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * Holds a batch of the configured {@code ScriptEngine} objects for the server.
@@ -342,16 +345,35 @@ public class ScriptEngines implements AutoCloseable {
                     final GroovyInterceptor interceptor = (GroovyInterceptor) providerClass.newInstance();
                     providers.add(new SecurityCustomizerProvider(interceptor));
                 } catch (Exception ex) {
-                    logger.warn("Could not instantiate GroovyInterceptor implementation [%s] for the SecurityCustomizerProvider.  It will not be applied.", clazz);
+                    logger.warn("Could not instantiate GroovyInterceptor implementation [{}] for the SecurityCustomizerProvider.  It will not be applied.", clazz);
                 }
             }
 
-            final long interruptionTimeout = ((Number) config.getOrDefault("interruptionTimeout",
-                    TimedInterruptCustomizerProvider.DEFAULT_INTERRUPTION_TIMEOUT)).longValue();
-            if (interruptionTimeout > 0) providers.add(new TimedInterruptCustomizerProvider(interruptionTimeout));
-
-            final boolean threadInterrupt = (boolean) config.getOrDefault("enableThreadInterrupt", true);
-            if (threadInterrupt) providers.add(new ThreadInterruptCustomizerProvider());
+            // the key to the config of the compilerCustomizerProvider is the fully qualified classname of a
+            // CompilerCustomizerProvider.  the value is a list of arguments to pass to an available constructor.
+            // the arguments must match in terms of type, so given that configuration typically comes from yaml
+            // or properties file, it is best to stick to primitive values when possible here for simplicity.
+            final Map<String,Object> compilerCustomizerProviders = (Map<String,Object>) config.getOrDefault(
+                    "compilerCustomizerProviders", Collections.emptyMap());
+            compilerCustomizerProviders.forEach((k,v) -> {
+                try {
+                    final Class providerClass = Class.forName(k);
+                    if (v != null && v instanceof List && ((List) v).size() > 0) {
+                        final List<Object> l = (List) v;
+                        final Object[] args = new Object[l.size()];
+                        l.toArray(args);
+
+                        final Class<?>[] argClasses = new Class<?>[args.length];
+                        Stream.of(args).map(a -> a.getClass()).collect(Collectors.toList()).toArray(argClasses);
+                        final Constructor constructor = providerClass.getConstructor(argClasses);
+                        providers.add((CompilerCustomizerProvider) constructor.newInstance(args));
+                    } else {
+                        providers.add((CompilerCustomizerProvider) providerClass.newInstance());
+                    }
+                } catch(Exception ex) {
+                    logger.warn("Could not instantiate CompilerCustomizerProvider implementation [{}].  It will not be applied.", clazz);
+                }
+            });
 
             final CompilerCustomizerProvider[] providerArray = new CompilerCustomizerProvider[providers.size()];
             return Optional.of((ScriptEngine) new GremlinGroovyScriptEngine(providers.toArray(providerArray)));

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/37796826/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 480c72f..6604b78 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
@@ -20,6 +20,8 @@ package org.apache.tinkerpop.gremlin.groovy.engine;
 
 import org.apache.commons.lang3.concurrent.BasicThreadFactory;
 import org.apache.tinkerpop.gremlin.TestHelper;
+import org.apache.tinkerpop.gremlin.groovy.ThreadInterruptCustomizerProvider;
+import org.apache.tinkerpop.gremlin.groovy.TimedInterruptCustomizerProvider;
 import org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngineTest;
 import org.junit.Test;
 import org.kohsuke.groovy.sandbox.GroovyInterceptor;
@@ -28,6 +30,7 @@ import javax.script.Bindings;
 import javax.script.CompiledScript;
 import javax.script.ScriptException;
 import javax.script.SimpleBindings;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -435,9 +438,14 @@ public class GremlinExecutorTest {
 
     @Test
     public void shouldContinueToEvalScriptsEvenWithTimedInterrupt() throws Exception {
-        GroovyInterceptor.getApplicableInterceptors().forEach(GroovyInterceptor::unregister);
+        final Map<String,List<Object>> compilerCustomizerConfig = new HashMap<>();
+        final List<Object> args = new ArrayList<>();
+        args.add(50);
+        compilerCustomizerConfig.put(TimedInterruptCustomizerProvider.class.getName(), args);
+
         final Map<String, Object> config = new HashMap<>();
-        config.put("interruptionTimeout", 50l);
+        config.put("compilerCustomizerProviders", compilerCustomizerConfig);
+
         final GremlinExecutor gremlinExecutor = GremlinExecutor.build()
                 .addEngineSettings("gremlin-groovy",
                         Collections.emptyList(),
@@ -462,6 +470,38 @@ public class GremlinExecutorTest {
         gremlinExecutor.close();
     }
 
+    @Test
+    public void shouldInterruptWhile() throws Exception {
+        final Map<String,List<Object>> compilerCustomizerConfig = new HashMap<>();
+        compilerCustomizerConfig.put(ThreadInterruptCustomizerProvider.class.getName(), new ArrayList<>());
+
+        final Map<String, Object> config = new HashMap<>();
+        config.put("compilerCustomizerProviders", compilerCustomizerConfig);
+
+        final GremlinExecutor gremlinExecutor = GremlinExecutor.build()
+                .addEngineSettings("gremlin-groovy",
+                        Collections.emptyList(),
+                        Collections.emptyList(),
+                        Arrays.asList(PATHS.get("GremlinExecutorInit.groovy")),
+                        config)
+                .create();
+        final AtomicBoolean asserted = new AtomicBoolean(false);
+
+        final Thread t = new Thread(() -> {
+            try {
+                gremlinExecutor.eval("s = System.currentTimeMillis();\nwhile((System.currentTimeMillis() - s) < 10000) {}").get();
+            } catch (Exception se) {
+                asserted.set(se instanceof InterruptedException);
+            }
+        });
+
+        t.start();
+        Thread.sleep(100);
+        t.interrupt();
+        while(t.isAlive()) {}
+
+        assertTrue(asserted.get());
+    }
 
     @Test
     public void shouldSecureAll() throws Exception {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/37796826/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTest.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTest.java
index 8f71588..19f56d8 100644
--- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTest.java
+++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngineTest.java
@@ -372,6 +372,7 @@ public class GremlinGroovyScriptEngineTest {
         });
 
         t.start();
+        Thread.sleep(100);
         t.interrupt();
         while(t.isAlive()) {}
 
@@ -394,6 +395,7 @@ public class GremlinGroovyScriptEngineTest {
         });
 
         t.start();
+        Thread.sleep(100);
         t.interrupt();
         while(t.isAlive()) {}