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 2018/12/17 20:12:21 UTC

[tinkerpop] 01/02: Added Cluster.using(Client) CTR

This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit f9d702757bbaf07a09ab13d534f2071a729610ee
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Mon Dec 17 14:51:40 2018 -0500

    Added Cluster.using(Client) CTR
---
 CHANGELOG.asciidoc                                 |  1 +
 docs/src/reference/gremlin-applications.asciidoc   | 15 ++++++-----
 .../driver/remote/DriverRemoteConnection.java      | 30 +++++++++++++++++++++-
 3 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 5e6dcb2..d8dc8bf 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -39,6 +39,7 @@ This release also includes changes from <<release-3-2-11, 3.2.11>>.
 * Changed Java driver to expect a generic `RemoteTraverser` object rather than the specific `DefaultRemoteTraverser`.
 * Display the remote stack trace in the Gremlin Console when scripts sent to the server fail.
 * Added `AnonymousTraversalSource` which provides a more unified means of constructing a `TraversalSource`.
+* Added `DriverRemoteConnection.using(Client)` to provide users better control over the number of connections being created.
 * Changed behavior of GraphSON deserializer in gremlin-python such that `g:Set` returns a Python `Set`.
 * Changed behavior of `iterate()` in Python, Javascript and .NET to send `none()` thus avoiding unnecessary results being returned.
 * Provided for a configurable class map cache in the `GremlinGroovyScriptEngine` and exposed that in Gremlin Server.
diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index 1ddb123..9ba581d 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -1075,22 +1075,22 @@ Note the call to `close()` above. The construction of "g" using the properties f
 `Client` instance that can only be released by "closing" the `GraphTraversalSource`. It is important to take that
 step to release resources created in that step.
 
-If working with multiple remote `TraversalSource` instances it is more efficient to construct a `Cluster` object and
+If working with multiple remote `TraversalSource` instances it is more efficient to construct a `Client` object and
 then re-use it.
 
 [gremlin-groovy]
 ----
 cluster = Cluster.open('conf/remote-objects.yaml')
-g = traversal().withRemote(DriverRemoteConnection.using(cluster, "g"))
+client = cluster.connect()
+g = traversal().withRemote(DriverRemoteConnection.using(client, "g"))
 g.V().valueMap(true)
 g.close()
 cluster.close()
 ----
 
-If the `Cluster` instance is supplied externally, as is shown above, then it is not closed implicitly by the close of
-"g".  Closing "g" will only close the `Client` instance associated with that `TraversalSource`. In this case, the
-`Cluster` must also be closed explicitly. Closing "g" and the "cluster" aren't actually both necessary - the close of
-a `Cluster` will close all `Client` instance spawned by the `Cluster`.
+If the `Client` instance is supplied externally, as is shown above, then it is not closed implicitly by the close of
+"g".  In this case, the `Client` and `Cluster` must both be closed explicitly. Closing "g" and the "cluster" aren'
+t actually both necessary - the close of a `Cluster` will close all `Client` instance spawned by the `Cluster`.
 
 IMPORTANT: `RemoteGraph` uses the `TraversalOpProcessor` in Gremlin Server which requires a cache to enable the
 retrieval of side-effects (if the `Traversal` produces any). That cache can be configured (e.g. controlling eviction
@@ -1104,8 +1104,9 @@ Gremlin-Groovy, use `Bindings`.
 [gremlin-groovy]
 ----
 cluster = Cluster.open('conf/remote-objects.yaml')
+client = cluster.connect()
 b = Bindings.instance()
-g = traversal().withRemote(DriverRemoteConnection.using(cluster, "g"))
+g = traversal().withRemote(DriverRemoteConnection.using(client, "g"))
 g.V(b.of('id',1)).out('created').values('name')
 g.V(b.of('id',4)).out('created').values('name')
 g.V(b.of('id',4)).out('created').values('name').getBytecode()
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnection.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnection.java
index 338a53b..1957fbd 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnection.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnection.java
@@ -55,6 +55,7 @@ public class DriverRemoteConnection implements RemoteConnection {
 
     private final Client client;
     private final boolean tryCloseCluster;
+    private final boolean tryCloseClient;
     private final String remoteTraversalSourceName;
     private transient Optional<Configuration> conf = Optional.empty();
 
@@ -81,6 +82,7 @@ public class DriverRemoteConnection implements RemoteConnection {
         }
 
         tryCloseCluster = true;
+        tryCloseClient = true;
         this.conf = Optional.of(conf);
     }
 
@@ -88,6 +90,7 @@ public class DriverRemoteConnection implements RemoteConnection {
         client = cluster.connect(Client.Settings.build().create()).alias(remoteTraversalSourceName);
         this.remoteTraversalSourceName = remoteTraversalSourceName;
         this.tryCloseCluster = tryCloseCluster;
+        tryCloseClient = true;
     }
 
     /**
@@ -98,9 +101,33 @@ public class DriverRemoteConnection implements RemoteConnection {
 
         client = cluster.connect(Client.Settings.build().create()).alias(remoteTraversalSourceName);
         tryCloseCluster = false;
+        tryCloseClient = true;
         this.conf = Optional.of(conf);
     }
 
+    private DriverRemoteConnection(final Client client, final String remoteTraversalSourceName) {
+        this.client = client;
+        this.remoteTraversalSourceName = remoteTraversalSourceName;
+        this.tryCloseCluster = false;
+        tryCloseClient = false;
+    }
+
+    /**
+     * Creates a {@link DriverRemoteConnection} using an existing {@link Client} object. The {@link Client} will not
+     * be closed on calls to {@link #close()}.
+     */
+    public static DriverRemoteConnection using(final Client client) {
+        return using(client, DEFAULT_TRAVERSAL_SOURCE);
+    }
+
+    /**
+     * Creates a {@link DriverRemoteConnection} using an existing {@link Client} object. The {@link Client} will not
+     * be closed on calls to {@link #close()}.
+     */
+    public static DriverRemoteConnection using(final Client client, final String remoteTraversalSourceName) {
+        return new DriverRemoteConnection(client, remoteTraversalSourceName);
+    }
+
     /**
      * Creates a {@link DriverRemoteConnection} using a new {@link Cluster} instance created from the supplied host
      * and port and binds it to a remote {@link GraphTraversalSource} named "g". When {@link #close()} is called,
@@ -229,7 +256,8 @@ public class DriverRemoteConnection implements RemoteConnection {
     @Override
     public void close() throws Exception {
         try {
-            client.close();
+            if (tryCloseClient)
+                client.close();
         } catch (Exception ex) {
             throw new RemoteConnectionException(ex);
         } finally {