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/09/28 18:48:39 UTC
tinkerpop git commit: Merge remote-tracking branch
'origin/TINKERPOP-1467' into TINKERPOP-1467-master
Repository: tinkerpop
Updated Branches:
refs/heads/TINKERPOP-1467-master [created] 6c84a71f5
Merge remote-tracking branch 'origin/TINKERPOP-1467' into TINKERPOP-1467-master
Conflicts:
CHANGELOG.asciidoc
gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java
gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Connection.java
gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/6c84a71f
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/6c84a71f
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/6c84a71f
Branch: refs/heads/TINKERPOP-1467-master
Commit: 6c84a71f5b50ba9e8a96b8ec766f26f1c8132b72
Parents: 7a4a836 934054f
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Sep 28 14:05:27 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Sep 28 14:05:27 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
.../upgrade/release-3.1.x-incubating.asciidoc | 17 +++++
.../tinkerpop/gremlin/driver/Channelizer.java | 2 +-
.../apache/tinkerpop/gremlin/driver/Client.java | 42 +++++++++--
.../tinkerpop/gremlin/driver/Cluster.java | 22 +++++-
.../tinkerpop/gremlin/driver/Connection.java | 56 +++++++++++++--
.../gremlin/driver/ConnectionPool.java | 21 +++---
.../tinkerpop/gremlin/driver/Handler.java | 26 +++++--
.../tinkerpop/gremlin/driver/ResultQueue.java | 4 ++
.../driver/handler/WebSocketClientHandler.java | 4 +-
.../server/GremlinDriverIntegrateTest.java | 74 +++++++++++++++++++-
.../server/GremlinServerAuthIntegrateTest.java | 5 +-
.../GremlinServerAuthOldIntegrateTest.java | 4 +-
.../GremlinServerSessionIntegrateTest.java | 6 +-
14 files changed, 241 insertions(+), 43 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6c84a71f/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --cc CHANGELOG.asciidoc
index 47d4bbf,66706d9..fba659b
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@@ -421,7 -26,7 +421,8 @@@ image::https://raw.githubusercontent.co
TinkerPop 3.1.5 (Release Date: NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* Fixed output redirection and potential memory leak in `GremlinGroovyScriptEngine`.
+ * Improved handling of `Cluster.close()` and `Client.close()` to prevent the methods from hanging.
* Corrected naming of `g_withPath_V_asXaX_out_out_mapXa_name_it_nameX` and `g_withPath_V_asXaX_out_mapXa_nameX` in `MapTest`.
* Improved session cleanup when a close is triggered by the client.
* Removed the `appveyor.yml` file as the AppVeyor build is no longer enabled by Apache Infrastructure.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6c84a71f/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Channelizer.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6c84a71f/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java
----------------------------------------------------------------------
diff --cc gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java
index 7b9262e,3a03141..bd397a1
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java
@@@ -350,11 -295,17 +355,17 @@@ public abstract class Client
public final static class ClusteredClient extends Client {
private ConcurrentMap<Host, ConnectionPool> hostConnectionPools = new ConcurrentHashMap<>();
+ private final AtomicReference<CompletableFuture<Void>> closing = new AtomicReference<>(null);
- ClusteredClient(final Cluster cluster) {
- super(cluster);
+ ClusteredClient(final Cluster cluster, final Client.Settings settings) {
+ super(cluster, settings);
}
+ @Override
+ public boolean isClosing() {
+ return closing.get() != null;
+ }
+
/**
* Submits a Gremlin script to the server and returns a {@link ResultSet} once the write of the request is
* complete.
@@@ -650,10 -503,12 +670,12 @@@
private ConnectionPool connectionPool;
+ private final AtomicReference<CompletableFuture<Void>> closing = new AtomicReference<>(null);
+
- SessionedClient(final Cluster cluster, final String sessionId, final boolean manageTransactions) {
- super(cluster);
- this.sessionId = sessionId;
- this.manageTransactions = manageTransactions;
+ SessionedClient(final Cluster cluster, final Client.Settings settings) {
+ super(cluster, settings);
+ this.sessionId = settings.getSession().get().sessionId;
+ this.manageTransactions = settings.getSession().get().manageTransactions;
}
String getSessionId() {
@@@ -697,134 -557,13 +724,139 @@@
* Close the bound {@link ConnectionPool}.
*/
@Override
- public CompletableFuture<Void> closeAsync() {
- return connectionPool.closeAsync();
+ public synchronized CompletableFuture<Void> closeAsync() {
+ if (closing.get() != null)
+ return closing.get();
+
+ final CompletableFuture<Void> connectionPoolClose = connectionPool.closeAsync();
+ closing.set(connectionPoolClose);
+ return connectionPoolClose;
}
}
+
+ /**
+ * Settings given to {@link Cluster#connect(Settings)} that configures how a {@link Client} will behave.
+ */
+ public static class Settings {
+ private final Optional<SessionSettings> session;
+
+ private Settings(final Builder builder) {
+ this.session = builder.session;
+ }
+
+ public static Builder build() {
+ return new Builder();
+ }
+
+ /**
+ * Determines if the {@link Client} is to be constructed with a session. If the value is present, then a
+ * session is expected.
+ */
+ public Optional<SessionSettings> getSession() {
+ return session;
+ }
+
+ public static class Builder {
+ private Optional<SessionSettings> session = Optional.empty();
+
+ private Builder() {}
+
+ /**
+ * Enables a session. By default this will create a random session name and configure transactions to be
+ * unmanaged. This method will override settings provided by calls to the other overloads of
+ * {@code useSession}.
+ */
+ public Builder useSession(final boolean enabled) {
+ session = enabled ? Optional.of(SessionSettings.build().create()) : Optional.empty();
+ return this;
+ }
+
+ /**
+ * Enables a session. By default this will create a session with the provided name and configure
+ * transactions to be unmanaged. This method will override settings provided by calls to the other
+ * overloads of {@code useSession}.
+ */
+ public Builder useSession(final String sessionId) {
+ session = sessionId != null && !sessionId.isEmpty() ?
+ Optional.of(SessionSettings.build().sessionId(sessionId).create()) : Optional.empty();
+ return this;
+ }
+
+ /**
+ * Enables a session. This method will override settings provided by calls to the other overloads of
+ * {@code useSession}.
+ */
+ public Builder useSession(final SessionSettings settings) {
+ session = Optional.ofNullable(settings);
+ return this;
+ }
+
+ public Settings create() {
+ return new Settings(this);
+ }
+
+ }
+ }
+
+ /**
+ * Settings for a {@link Client} that involve a session.
+ */
+ public static class SessionSettings {
+ private final boolean manageTransactions;
+ private final String sessionId;
+
+ private SessionSettings(final Builder builder) {
+ manageTransactions = builder.manageTransactions;
+ sessionId = builder.sessionId;
+ }
+
+ /**
+ * If enabled, transactions will be "managed" such that each request will represent a complete transaction.
+ */
+ public boolean manageTransactions() {
+ return manageTransactions;
+ }
+
+ /**
+ * Provides the identifier of the session.
+ */
+ public String getSessionId() {
+ return sessionId;
+ }
+
+ public static SessionSettings.Builder build() {
+ return new SessionSettings.Builder();
+ }
+
+ public static class Builder {
+ private boolean manageTransactions = false;
+ private String sessionId = UUID.randomUUID().toString();
+
+ private Builder() {}
+
+ /**
+ * If enabled, transactions will be "managed" such that each request will represent a complete transaction.
+ * By default this value is {@code false}.
+ */
+ public Builder manageTransactions(final boolean manage) {
+ manageTransactions = manage;
+ return this;
+ }
+
+ /**
+ * Provides the identifier of the session. This value cannot be null or empty. By default it is set to
+ * a random {@code UUID}.
+ */
+ public Builder sessionId(final String sessionId) {
+ if (null == sessionId || sessionId.isEmpty())
+ throw new IllegalArgumentException("sessionId cannot be null or empty");
+ this.sessionId = sessionId;
+ return this;
+ }
+
+ public SessionSettings create() {
+ return new SessionSettings(this);
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6c84a71f/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
----------------------------------------------------------------------
diff --cc gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
index f79e719,473991a..f426a3c
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Cluster.java
@@@ -84,7 -84,9 +85,9 @@@ public final class Cluster
* submitted or can be directly initialized via {@link Client#init()}.
*/
public <T extends Client> T connect() {
- return (T) new Client.ClusteredClient(this, Client.Settings.build().create());
- final Client client = new Client.ClusteredClient(this);
++ final Client client = new Client.ClusteredClient(this, Client.Settings.build().create());
+ manager.trackClient(client);
+ return (T) client;
}
/**
@@@ -121,21 -123,13 +124,23 @@@
* @param manageTransactions enables auto-transactions when set to true
*/
public <T extends Client> T connect(final String sessionId, final boolean manageTransactions) {
- if (null == sessionId || sessionId.isEmpty())
- throw new IllegalArgumentException("sessionId cannot be null or empty");
- final Client client = new Client.SessionedClient(this, sessionId, manageTransactions);
+ final Client.SessionSettings sessionSettings = Client.SessionSettings.build()
+ .manageTransactions(manageTransactions)
+ .sessionId(sessionId).create();
+ final Client.Settings settings = Client.Settings.build().useSession(sessionSettings).create();
- return connect(settings);
++ final Client client = connect(settings);
+ manager.trackClient(client);
+ return (T) client;
}
+ /**
+ * Creates a new {@link Client} based on the settings provided.
+ */
+ public <T extends Client> T connect(final Client.Settings settings) {
+ return settings.getSession().isPresent() ? (T) new Client.SessionedClient(this, settings) :
+ (T) new Client.ClusteredClient(this, settings);
+ }
+
@Override
public String toString() {
return manager.toString();
@@@ -862,12 -687,10 +867,14 @@@
private final ScheduledExecutorService executor;
+ private final int nioPoolSize;
+ private final int workerPoolSize;
+ private final int port;
+
private final AtomicReference<CompletableFuture<Void>> closeFuture = new AtomicReference<>();
+ private final List<WeakReference<Client>> openedClients = new ArrayList<>();
+
private Manager(final Builder builder) {
this.loadBalancingStrategy = builder.loadBalancingStrategy;
this.authProps = builder.authProps;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6c84a71f/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Connection.java
----------------------------------------------------------------------
diff --cc gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Connection.java
index 1ef9b98,766db2e..8576de5
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Connection.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Connection.java
@@@ -153,15 -150,12 +154,16 @@@ final class Connection
return pending;
}
- public CompletableFuture<Void> closeAsync() {
+ public synchronized CompletableFuture<Void> closeAsync() {
+ if (isClosed()) return closeFuture.get();
+
final CompletableFuture<Void> future = new CompletableFuture<>();
- if (!closeFuture.compareAndSet(null, future))
- return closeFuture.get();
+ closeFuture.set(future);
+ // stop any pings being sent at the server for keep-alive
+ final ScheduledFuture keepAlive = keepAliveFuture.get();
+ if (keepAlive != null) keepAlive.cancel(true);
+
// make sure all requests in the queue are fully processed before killing. if they are then shutdown
// can be immediate. if not this method will signal the readCompleted future defined in the write()
// operation to check if it can close. in this way the connection no longer receives writes, but
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6c84a71f/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ConnectionPool.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6c84a71f/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6c84a71f/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ResultQueue.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6c84a71f/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/WebSocketClientHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6c84a71f/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
index 96cde54,8f24de2..5c0e903
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
@@@ -26,9 -25,7 +26,8 @@@ import org.apache.tinkerpop.gremlin.dri
import org.apache.tinkerpop.gremlin.driver.Cluster;
import org.apache.tinkerpop.gremlin.driver.Result;
import org.apache.tinkerpop.gremlin.driver.ResultSet;
- import org.apache.tinkerpop.gremlin.driver.exception.ConnectionException;
import org.apache.tinkerpop.gremlin.driver.exception.ResponseException;
+import org.apache.tinkerpop.gremlin.driver.handler.WebSocketClientHandler;
import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
import org.apache.tinkerpop.gremlin.driver.ser.JsonBuilderGryoSerializer;
import org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0;