You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by fl...@apache.org on 2018/08/02 19:13:23 UTC

[1/6] tinkerpop git commit: CTR: Fixed build by adding python3-dev dependency to the base image Dockerfile [Forced Update!]

Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1774 e35ef0af1 -> f4d277540 (forced update)


CTR: Fixed build by adding python3-dev dependency to the base image Dockerfile


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

Branch: refs/heads/TINKERPOP-1774
Commit: 7fce1377f70190954f858901c7a3698dbd17cf82
Parents: e3018fb
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Wed Aug 1 11:26:51 2018 -0700
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Wed Aug 1 11:26:51 2018 -0700

----------------------------------------------------------------------
 docker/Dockerfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7fce1377/docker/Dockerfile
----------------------------------------------------------------------
diff --git a/docker/Dockerfile b/docker/Dockerfile
index dbc06ef..9ae74aa 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -30,7 +30,7 @@ RUN apt-get update \
     && apt-get update \
     && apt-get install -y oracle-java8-installer curl gawk git maven openssh-server subversion zip \
     && sh -c 'curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg' \
-    && apt-get install -y --force-yes dotnet-sdk-2.1.101 python python-dev python-pip build-essential mono-devel \
+    && apt-get install -y --force-yes dotnet-sdk-2.1.101 python python-dev python3-dev python-pip build-essential mono-devel \
     && pip install virtualenv virtualenvwrapper \
     && pip install --upgrade pip \
     && rm -rf /var/lib/apt/lists/* /var/cache/oracle-jdk8-installer


[5/6] tinkerpop git commit: Add ConnectionPool min and max sizes TINKERPOP-1774

Posted by fl...@apache.org.
Add ConnectionPool min and max sizes TINKERPOP-1774

The Gremlin.Net ConnectionPool now has min and max sizes. The pool will
be initialized with the configured minimum number of connections on
creation. It will also no longer create an unlimited number of
connections. Instead, a TimeoutException will be thrown when the max
limit is reached and no connection became available within a
configurable time.


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

Branch: refs/heads/TINKERPOP-1774
Commit: 2fbdb8e34fa8df7c6b5cc3a462875934de82ff77
Parents: 8f1fe6d
Author: Florian Hockmann <fh...@florian-hockmann.de>
Authored: Mon Jul 30 21:45:26 2018 +0200
Committer: Florian Hockmann <fh...@florian-hockmann.de>
Committed: Thu Aug 2 16:46:55 2018 +0200

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 docs/src/upgrade/release-3.4.x.asciidoc         |  11 ++
 .../src/Gremlin.Net/Driver/Connection.cs        |  16 +--
 .../src/Gremlin.Net/Driver/ConnectionPool.cs    | 129 +++++++++++++------
 .../Driver/ConnectionPoolSettings.cs            |  55 ++++++++
 .../src/Gremlin.Net/Driver/GremlinClient.cs     |   7 +-
 .../Driver/GremlinClientExtensions.cs           |  12 +-
 .../Driver/Remote/DriverRemoteConnection.cs     |   4 +-
 .../Gremlin.Net/Driver/WebSocketConnection.cs   |  16 +--
 .../Driver/ConnectionPoolTests.cs               |  68 ++++++++--
 .../RemoteConnectionFactory.cs                  |   4 +-
 11 files changed, 239 insertions(+), 84 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2fbdb8e3/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 430f52d..ed1ea6b 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -25,6 +25,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 
 This release also includes changes from <<release-3-3-3, 3.3.3>>.
 
+* Added min and max connection pool sizes for Gremlin.Net which are configurable through optional ConnectionPoolSettings.
 * `AbstractGraphProvider` uses `g.io()` for loading test data.
 * Added the `io()` start step and `read()` and `write()` termination steps to the Gremlin language.
 * Added `GraphFeatures.supportsIoRead()` and `GraphFeatures.supportsIoWrite()`.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2fbdb8e3/docs/src/upgrade/release-3.4.x.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.4.x.asciidoc b/docs/src/upgrade/release-3.4.x.asciidoc
index 9951024..73cbd08 100644
--- a/docs/src/upgrade/release-3.4.x.asciidoc
+++ b/docs/src/upgrade/release-3.4.x.asciidoc
@@ -177,6 +177,17 @@ when dealing with that event. To make this easier, the event now raises with a `
 
 link:https://issues.apache.org/jira/browse/TINKERPOP-1831[TINKERPOP-1831]
 
+==== Gremlin.Net: Configurable Max and Min ConnectionPool Sizes
+
+Gremlin.Net's `ConnectionPool` now has a minimum and a maximum size. These sizes are configurable through added
+`ConnectionPoolSettings`. The minimum size determines how many connections are initially created. The maximum size
+is an upper limit of connections that can be created. When this limit is reached and another connection is needed,
+then the connection pool waits for a connection to become available again. The time to be waited is limited by the
+newly introduced option `ConnectionPoolSettings.WaitForConnectionTimeout`. A `TimeoutException` is thrown when
+no connection becomes available until this timeout is reached.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1774[TINKERPOP-1774]
+
 ==== Deprecation Removal
 
 The following deprecated classes, methods or fields have been removed in this version:

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2fbdb8e3/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
index 279c708..2452e3e 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
@@ -59,23 +59,23 @@ namespace Gremlin.Net.Driver
             return await ReceiveAsync<T>().ConfigureAwait(false);
         }
 
-        public async Task ConnectAsync()
+        public Task ConnectAsync()
         {
-            await _webSocketConnection.ConnectAsync(_uri).ConfigureAwait(false);
+            return _webSocketConnection.ConnectAsync(_uri);
         }
 
-        public async Task CloseAsync()
+        public Task CloseAsync()
         {
-            await _webSocketConnection.CloseAsync().ConfigureAwait(false);
+            return _webSocketConnection.CloseAsync();
         }
 
         public bool IsOpen => _webSocketConnection.IsOpen;
 
-        private async Task SendAsync(RequestMessage message)
+        private Task SendAsync(RequestMessage message)
         {
             var graphsonMsg = _graphSONWriter.WriteObject(message);
             var serializedMsg = _messageSerializer.SerializeMessage(graphsonMsg);
-            await _webSocketConnection.SendMessageAsync(serializedMsg).ConfigureAwait(false);
+            return _webSocketConnection.SendMessageAsync(serializedMsg);
         }
 
         private async Task<IReadOnlyCollection<T>> ReceiveAsync<T>()
@@ -121,7 +121,7 @@ namespace Gremlin.Net.Driver
             return result;
         }
 
-        private async Task AuthenticateAsync()
+        private Task AuthenticateAsync()
         {
             if (string.IsNullOrEmpty(_username) || string.IsNullOrEmpty(_password))
                 throw new InvalidOperationException(
@@ -130,7 +130,7 @@ namespace Gremlin.Net.Driver
             var message = RequestMessage.Build(Tokens.OpsAuthentication).Processor(Tokens.ProcessorTraversal)
                 .AddArgument(Tokens.ArgsSasl, SaslArgument()).Create();
 
-            await SendAsync(message).ConfigureAwait(false);
+            return SendAsync(message);
         }
 
         private string SaslArgument()

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2fbdb8e3/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
index d9e53f4..a65208a 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
@@ -23,7 +23,8 @@
 
 using System;
 using System.Collections.Concurrent;
-using System.Linq;
+using System.Collections.Generic;
+using System.Threading;
 using System.Threading.Tasks;
 using Gremlin.Net.Process;
 
@@ -33,91 +34,134 @@ namespace Gremlin.Net.Driver
     {
         private readonly ConnectionFactory _connectionFactory;
         private readonly ConcurrentBag<Connection> _connections = new ConcurrentBag<Connection>();
-        private readonly object _connectionsLock = new object();
+        private readonly AutoResetEvent _newConnectionAvailable = new AutoResetEvent(false);
+        private readonly int _minPoolSize;
+        private readonly int _maxPoolSize;
+        private readonly TimeSpan _waitForConnectionTimeout;
+        private int _nrConnections;
 
-        public ConnectionPool(ConnectionFactory connectionFactory)
+        public ConnectionPool(ConnectionFactory connectionFactory, ConnectionPoolSettings settings)
         {
             _connectionFactory = connectionFactory;
+            _minPoolSize = settings.MinSize;
+            _maxPoolSize = settings.MaxSize;
+            _waitForConnectionTimeout = settings.WaitForConnectionTimeout;
+            PopulatePoolAsync().WaitUnwrap();
         }
 
-        public int NrConnections { get; private set; }
+        public int NrConnections => Interlocked.CompareExchange(ref _nrConnections, 0, 0);
+
+        private async Task PopulatePoolAsync()
+        {
+            var connectionCreationTasks = new List<Task<Connection>>(_minPoolSize);
+            for (var i = 0; i < _minPoolSize; i++)
+            {
+                connectionCreationTasks.Add(CreateNewConnectionAsync());
+            }
+
+            var createdConnections = await Task.WhenAll(connectionCreationTasks).ConfigureAwait(false);
+            foreach (var c in createdConnections)
+            {
+                _connections.Add(c);
+            }
+
+            Interlocked.CompareExchange(ref _nrConnections, _minPoolSize, 0);
+        }
 
         public async Task<IConnection> GetAvailableConnectionAsync()
         {
-            if (!TryGetConnectionFromPool(out var connection))
-                connection = await CreateNewConnectionAsync().ConfigureAwait(false);
+            if (TryGetConnectionFromPool(out var connection))
+                return ProxiedConnection(connection);
+            connection = await AddConnectionIfUnderMaximumAsync().ConfigureAwait(false) ?? WaitForConnection();
+            return ProxiedConnection(connection);
+        }
 
-            return new ProxyConnection(connection, AddConnectionIfOpen);
+        private IConnection ProxiedConnection(Connection connection)
+        {
+            return new ProxyConnection(connection, ReturnConnectionIfOpen);
         }
 
-        private bool TryGetConnectionFromPool(out Connection connection)
+        private void ReturnConnectionIfOpen(Connection connection)
+        {
+            if (!connection.IsOpen)
+            {
+                ConsiderUnavailable();
+                DefinitelyDestroyConnection(connection);
+                return;
+            }
+
+            _connections.Add(connection);
+            _newConnectionAvailable.Set();
+        }
+
+        private async Task<Connection> AddConnectionIfUnderMaximumAsync()
         {
             while (true)
             {
-                connection = null;
-                lock (_connectionsLock)
-                {
-                    if (_connections.IsEmpty) return false;
-                    _connections.TryTake(out connection);
-                }
+                var nrOpened = Interlocked.CompareExchange(ref _nrConnections, 0, 0);
+                if (nrOpened >= _maxPoolSize) return null;
 
-                if (connection.IsOpen) return true;
-                connection.Dispose();
+                if (Interlocked.CompareExchange(ref _nrConnections, nrOpened + 1, nrOpened) == nrOpened)
+                    break;
             }
+
+            return await CreateNewConnectionAsync().ConfigureAwait(false);
         }
 
         private async Task<Connection> CreateNewConnectionAsync()
         {
-            NrConnections++;
             var newConnection = _connectionFactory.CreateConnection();
             await newConnection.ConnectAsync().ConfigureAwait(false);
             return newConnection;
         }
 
-        private void AddConnectionIfOpen(Connection connection)
+        private Connection WaitForConnection()
         {
-            if (!connection.IsOpen)
+            var start = DateTimeOffset.Now;
+            var remaining = _waitForConnectionTimeout;
+            do
             {
-                ConsiderUnavailable();
-                connection.Dispose();
-                return;
-            }
-            AddConnection(connection);
+                if (_newConnectionAvailable.WaitOne(remaining))
+                {
+                    if (TryGetConnectionFromPool(out var connection))
+                        return connection;
+                }
+                remaining = _waitForConnectionTimeout - (DateTimeOffset.Now - start);
+            } while (remaining > TimeSpan.Zero);
+
+            ConsiderUnavailable();
+            throw new TimeoutException("Timed out while waiting for an available connection.");
         }
 
-        private void AddConnection(Connection connection)
+        private bool TryGetConnectionFromPool(out Connection connection)
         {
-            lock (_connectionsLock)
+            while (true)
             {
-                _connections.Add(connection);
+                _connections.TryTake(out connection);
+                if (connection == null) return false; // _connections is empty
+                if (connection.IsOpen) return true;
+                DefinitelyDestroyConnection(connection);
             }
         }
 
         private void ConsiderUnavailable()
         {
-            CloseAndRemoveAllConnections();
-        }
-
-        private void CloseAndRemoveAllConnections()
-        {
-            lock (_connectionsLock)
-            {
-                TeardownAsync().WaitUnwrap();
-                RemoveAllConnections();
-            }
+            CloseAndRemoveAllConnectionsAsync().WaitUnwrap();
         }
 
-        private void RemoveAllConnections()
+        private async Task CloseAndRemoveAllConnectionsAsync()
         {
             while (_connections.TryTake(out var connection))
             {
-                connection.Dispose();
+                await connection.CloseAsync().ConfigureAwait(false);
+                DefinitelyDestroyConnection(connection);
             }
         }
 
-        private async Task TeardownAsync()
+        private void DefinitelyDestroyConnection(Connection connection)
         {
-            await Task.WhenAll(_connections.Select(c => c.CloseAsync())).ConfigureAwait(false);
+            connection.Dispose();
+            Interlocked.Decrement(ref _nrConnections);
         }
 
         #region IDisposable Support
@@ -135,10 +179,11 @@ namespace Gremlin.Net.Driver
             if (!_disposed)
             {
                 if (disposing)
-                    CloseAndRemoveAllConnections();
+                    CloseAndRemoveAllConnectionsAsync().WaitUnwrap();
                 _disposed = true;
             }
         }
+
         #endregion
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2fbdb8e3/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPoolSettings.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPoolSettings.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPoolSettings.cs
new file mode 100644
index 0000000..b156137
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPoolSettings.cs
@@ -0,0 +1,55 @@
+#region License
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#endregion
+
+using System;
+
+namespace Gremlin.Net.Driver
+{
+    /// <summary>
+    ///     Holds settings for the <see cref="ConnectionPool"/>.
+    /// </summary>
+    public class ConnectionPoolSettings
+    {
+        private const int DefaultMinPoolSize = 8;
+        private const int DefaultMaxPoolSize = 128;
+        private static readonly TimeSpan DefaultWaitForConnectionTimeout = TimeSpan.FromSeconds(3);
+
+        /// <summary>
+        ///     Gets or sets the minimum size of a connection pool.
+        /// </summary>
+        /// <remarks>The default value is 8.</remarks>
+        public int MinSize { get; set; } = DefaultMinPoolSize;
+
+        /// <summary>
+        ///     Gets or sets the maximum size of a connection pool.
+        /// </summary>
+        /// <remarks>The default value is 128.</remarks>
+        public int MaxSize { get; set; } = DefaultMaxPoolSize;
+
+        /// <summary>
+        ///     Gets or sets the timespan to wait for a new connection before timing out.
+        /// </summary>
+        /// <remarks>The default value is 3 seconds.</remarks>
+        public TimeSpan WaitForConnectionTimeout { get; set; } = DefaultWaitForConnectionTimeout;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2fbdb8e3/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs
index 2b47cbc..41f08d1 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClient.cs
@@ -53,13 +53,16 @@ namespace Gremlin.Net.Driver
         /// <param name="graphSONReader">A <see cref="GraphSONReader" /> instance to read received GraphSON data.</param>
         /// <param name="graphSONWriter">a <see cref="GraphSONWriter" /> instance to write GraphSON data.</param>
         /// <param name="mimeType">The GraphSON version mime type, defaults to latest supported by the server.</param>
+        /// <param name="connectionPoolSettings">The <see cref="ConnectionPoolSettings"/> for the connection pool.</param>
         public GremlinClient(GremlinServer gremlinServer, GraphSONReader graphSONReader = null,
-                             GraphSONWriter graphSONWriter = null, string mimeType = null)
+            GraphSONWriter graphSONWriter = null, string mimeType = null,
+            ConnectionPoolSettings connectionPoolSettings = null)
         {
             var reader = graphSONReader ?? new GraphSON3Reader();
             var writer = graphSONWriter ?? new GraphSON3Writer();
             var connectionFactory = new ConnectionFactory(gremlinServer, reader, writer, mimeType ?? DefaultMimeType);
-            _connectionPool = new ConnectionPool(connectionFactory);
+            _connectionPool =
+                new ConnectionPool(connectionFactory, connectionPoolSettings ?? new ConnectionPoolSettings());
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2fbdb8e3/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs
index 4aad73e..1365b2f 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinClientExtensions.cs
@@ -92,10 +92,10 @@ namespace Gremlin.Net.Driver
         ///     Thrown when a response is received from Gremlin Server that indicates
         ///     that an error occurred.
         /// </exception>
-        public static async Task SubmitAsync(this IGremlinClient gremlinClient, string requestScript,
+        public static Task SubmitAsync(this IGremlinClient gremlinClient, string requestScript,
             Dictionary<string, object> bindings = null)
         {
-            await gremlinClient.SubmitAsync<object>(requestScript, bindings).ConfigureAwait(false);
+            return gremlinClient.SubmitAsync<object>(requestScript, bindings);
         }
 
         /// <summary>
@@ -109,9 +109,9 @@ namespace Gremlin.Net.Driver
         ///     Thrown when a response is received from Gremlin Server that indicates
         ///     that an error occurred.
         /// </exception>
-        public static async Task SubmitAsync(this IGremlinClient gremlinClient, RequestMessage requestMessage)
+        public static Task SubmitAsync(this IGremlinClient gremlinClient, RequestMessage requestMessage)
         {
-            await gremlinClient.SubmitAsync<object>(requestMessage).ConfigureAwait(false);
+            return gremlinClient.SubmitAsync<object>(requestMessage);
         }
 
         /// <summary>
@@ -126,7 +126,7 @@ namespace Gremlin.Net.Driver
         ///     Thrown when a response is received from Gremlin Server that indicates
         ///     that an error occurred.
         /// </exception>
-        public static async Task<IReadOnlyCollection<T>> SubmitAsync<T>(this IGremlinClient gremlinClient,
+        public static Task<IReadOnlyCollection<T>> SubmitAsync<T>(this IGremlinClient gremlinClient,
             string requestScript,
             Dictionary<string, object> bindings = null)
         {
@@ -134,7 +134,7 @@ namespace Gremlin.Net.Driver
             if (bindings != null)
                 msgBuilder.AddArgument(Tokens.ArgsBindings, bindings);
             var msg = msgBuilder.Create();
-            return await gremlinClient.SubmitAsync<T>(msg).ConfigureAwait(false);
+            return gremlinClient.SubmitAsync<T>(msg);
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2fbdb8e3/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs
index 8cbd43d..2c3fc28 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteConnection.cs
@@ -71,7 +71,7 @@ namespace Gremlin.Net.Driver.Remote
             return new DriverRemoteTraversal<S, E>(_client, requestId, resultSet);
         }
 
-        private async Task<IEnumerable<Traverser>> SubmitBytecodeAsync(Guid requestid, Bytecode bytecode)
+        private Task<IReadOnlyCollection<Traverser>> SubmitBytecodeAsync(Guid requestid, Bytecode bytecode)
         {
             var requestMsg =
                 RequestMessage.Build(Tokens.OpsBytecode)
@@ -80,7 +80,7 @@ namespace Gremlin.Net.Driver.Remote
                     .AddArgument(Tokens.ArgsGremlin, bytecode)
                     .AddArgument(Tokens.ArgsAliases, new Dictionary<string, string> {{"g", _traversalSource}})
                     .Create();
-            return await _client.SubmitAsync<Traverser>(requestMsg).ConfigureAwait(false);
+            return _client.SubmitAsync<Traverser>(requestMsg);
         }
 
         /// <inheritdoc />

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2fbdb8e3/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs
index 9672606..1196359 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs
@@ -35,24 +35,20 @@ namespace Gremlin.Net.Driver
         private const WebSocketMessageType MessageType = WebSocketMessageType.Binary;
         private ClientWebSocket _client;
 
-        public async Task ConnectAsync(Uri uri)
+        public Task ConnectAsync(Uri uri)
         {
             _client = new ClientWebSocket();
-            await _client.ConnectAsync(uri, CancellationToken.None).ConfigureAwait(false);
+            return _client.ConnectAsync(uri, CancellationToken.None);
         }
 
-        public async Task CloseAsync()
+        public Task CloseAsync()
         {
-            await
-                _client.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None)
-                    .ConfigureAwait(false);
+            return _client.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
         }
 
-        public async Task SendMessageAsync(byte[] message)
+        public Task SendMessageAsync(byte[] message)
         {
-            await
-                _client.SendAsync(new ArraySegment<byte>(message), MessageType, true, CancellationToken.None)
-                    .ConfigureAwait(false);
+            return _client.SendAsync(new ArraySegment<byte>(message), MessageType, true, CancellationToken.None);
         }
 
         public async Task<byte[]> ReceiveMessageAsync()

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2fbdb8e3/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs
index 21a2627..a93a383 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/ConnectionPoolTests.cs
@@ -49,8 +49,8 @@ namespace Gremlin.Net.IntegrationTest.Driver
         [Fact]
         public async Task ShouldReuseConnectionForSequentialRequests()
         {
-            var gremlinServer = new GremlinServer(TestHost, TestPort);
-            using (var gremlinClient = new GremlinClient(gremlinServer))
+            const int minConnectionPoolSize = 1;
+            using (var gremlinClient = CreateGremlinClient(minConnectionPoolSize))
             {
                 await gremlinClient.SubmitAsync("");
                 await gremlinClient.SubmitAsync("");
@@ -60,31 +60,73 @@ namespace Gremlin.Net.IntegrationTest.Driver
             }
         }
 
-        [Fact]
-        public void ShouldOnlyCreateConnectionWhenNecessary()
+        [Theory]
+        [InlineData(0)]
+        [InlineData(1)]
+        [InlineData(8)]
+        public void ShouldStartWithConfiguredNrMinConnections(int minConnectionPoolSize)
         {
-            var gremlinServer = new GremlinServer(TestHost, TestPort);
-            using (var gremlinClient = new GremlinClient(gremlinServer))
+            using (var gremlinClient = CreateGremlinClient(minConnectionPoolSize))
             {
                 var nrConnections = gremlinClient.NrConnections;
-                Assert.Equal(0, nrConnections);
+                Assert.Equal(minConnectionPoolSize, nrConnections);
             }
         }
 
         [Fact]
         public async Task ShouldExecuteParallelRequestsOnDifferentConnections()
         {
-            var gremlinServer = new GremlinServer(TestHost, TestPort);
-            using (var gremlinClient = new GremlinClient(gremlinServer))
+            const int nrParallelRequests = 5;
+            using (var gremlinClient = CreateGremlinClient(nrParallelRequests))
             {
-                var sleepTime = 50;
-                var nrParallelRequests = 5;
+                const int sleepTime = 50;
 
                 await ExecuteMultipleLongRunningRequestsInParallel(gremlinClient, nrParallelRequests, sleepTime);
 
-                var nrConnections = gremlinClient.NrConnections;
-                Assert.Equal(nrParallelRequests, nrConnections);
+                Assert.Equal(nrParallelRequests, gremlinClient.NrConnections);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldNotCreateMoreThanConfiguredNrMaxConnections()
+        {
+            const int maxConnectionPoolSize = 1;
+            using (var gremlinClient = CreateGremlinClient(maxConnectionPoolSize: maxConnectionPoolSize))
+            {
+                const int sleepTime = 100;
+
+                await ExecuteMultipleLongRunningRequestsInParallel(gremlinClient, maxConnectionPoolSize + 1, sleepTime);
+
+                Assert.Equal(maxConnectionPoolSize, gremlinClient.NrConnections);
+            }
+        }
+
+        [Fact]
+        public async Task ShouldThrowTimeoutExceptionWhenNoConnectionIsAvailable()
+        {
+            const int nrParallelRequests = 3;
+            const int waitForConnectionTimeoutInMs = 5;
+            using (var gremlinClient = CreateGremlinClient(maxConnectionPoolSize: nrParallelRequests - 1,
+                waitForConnectionTimeoutInMs: waitForConnectionTimeoutInMs))
+            {
+                const int sleepTime = 100;
+
+                await Assert.ThrowsAsync<TimeoutException>(() =>
+                    ExecuteMultipleLongRunningRequestsInParallel(gremlinClient, nrParallelRequests, sleepTime));
             }
         }
+
+        private static GremlinClient CreateGremlinClient(int minConnectionPoolSize = 0, int maxConnectionPoolSize = 8,
+            int waitForConnectionTimeoutInMs = 5000)
+        {
+            var gremlinServer = new GremlinServer(TestHost, TestPort);
+            return new GremlinClient(gremlinServer,
+                connectionPoolSettings: new ConnectionPoolSettings
+                {
+                    MinSize = minConnectionPoolSize,
+                    MaxSize = maxConnectionPoolSize,
+                    WaitForConnectionTimeout = TimeSpan.FromMilliseconds(waitForConnectionTimeoutInMs)
+                });
+        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2fbdb8e3/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/RemoteConnectionFactory.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/RemoteConnectionFactory.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/RemoteConnectionFactory.cs
index 39b7fea..088db59 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/RemoteConnectionFactory.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/DriverRemoteConnection/RemoteConnectionFactory.cs
@@ -44,7 +44,9 @@ namespace Gremlin.Net.IntegrationTest.Process.Traversal.DriverRemoteConnection
 
         public IRemoteConnection CreateRemoteConnection(string traversalSource)
         {
-            var c = new DriverRemoteConnectionImpl(new GremlinClient(new GremlinServer(TestHost, TestPort)),
+            var c = new DriverRemoteConnectionImpl(
+                new GremlinClient(new GremlinServer(TestHost, TestPort),
+                    connectionPoolSettings: new ConnectionPoolSettings {MinSize = 1}),
                 traversalSource);
             _connections.Add(c);
             return c;


[2/6] tinkerpop git commit: Merge branch 'tp32' into tp33

Posted by fl...@apache.org.
Merge branch 'tp32' into tp33


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

Branch: refs/heads/TINKERPOP-1774
Commit: 8af7837286c7eba82c831576a3291c77bfb727e9
Parents: dfe79c2 7fce137
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Wed Aug 1 11:27:04 2018 -0700
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Wed Aug 1 11:27:04 2018 -0700

----------------------------------------------------------------------
 docker/Dockerfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------



[3/6] tinkerpop git commit: Merge branch 'tp33'

Posted by fl...@apache.org.
Merge branch 'tp33'


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

Branch: refs/heads/TINKERPOP-1774
Commit: 69b6f96d7ac8aa706ce65dee436d7038b8b3eaac
Parents: b183edd 8af7837
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Wed Aug 1 11:27:17 2018 -0700
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Wed Aug 1 11:27:17 2018 -0700

----------------------------------------------------------------------
 docker/Dockerfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------



[6/6] tinkerpop git commit: Add Gremlin.Net driver settings docs TINKERPOP-1774

Posted by fl...@apache.org.
Add Gremlin.Net driver settings docs TINKERPOP-1774


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

Branch: refs/heads/TINKERPOP-1774
Commit: f4d27754080eb03df0a217d7d342ffc7f47b2f5c
Parents: 2fbdb8e
Author: Florian Hockmann <fh...@florian-hockmann.de>
Authored: Thu Aug 2 18:45:49 2018 +0200
Committer: Florian Hockmann <fh...@florian-hockmann.de>
Committed: Thu Aug 2 20:06:45 2018 +0200

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  2 +-
 docs/src/dev/provider/index.asciidoc            |  4 +-
 .../src/reference/gremlin-applications.asciidoc |  1 +
 docs/src/reference/gremlin-variants.asciidoc    | 45 +++++++++++++++++++-
 docs/src/upgrade/release-3.4.x.asciidoc         |  4 +-
 .../Driver/ConnectionPoolSettings.cs            |  2 +-
 .../src/Gremlin.Net/Driver/GremlinServer.cs     |  3 +-
 7 files changed, 53 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f4d27754/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index ed1ea6b..bda3fe6 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -25,7 +25,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 
 This release also includes changes from <<release-3-3-3, 3.3.3>>.
 
-* Added min and max connection pool sizes for Gremlin.Net which are configurable through optional ConnectionPoolSettings.
+* Added min and max connection pool sizes for Gremlin.Net which are configurable through optional `ConnectionPoolSettings`.
 * `AbstractGraphProvider` uses `g.io()` for loading test data.
 * Added the `io()` start step and `read()` and `write()` termination steps to the Gremlin language.
 * Added `GraphFeatures.supportsIoRead()` and `GraphFeatures.supportsIoWrite()`.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f4d27754/docs/src/dev/provider/index.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/dev/provider/index.asciidoc b/docs/src/dev/provider/index.asciidoc
index ab57020..6118a75 100644
--- a/docs/src/dev/provider/index.asciidoc
+++ b/docs/src/dev/provider/index.asciidoc
@@ -572,9 +572,9 @@ internal class MyTypeReader : IGraphSONDeserializer
     }
 }
 
-var graphsonReader = new GraphSONReader(
+var graphsonReader = new GraphSON3Reader(
     new Dictionary<string, IGraphSONDeserializer> {{MyType.GraphsonType, new MyTypeReader()}});
-var graphsonWriter = new GraphSONWriter(
+var graphsonWriter = new GraphSON3Writer(
     new Dictionary<Type, IGraphSONSerializer> {{typeof(MyType), new MyClassWriter()}});
 
 var gremlinClient = new GremlinClient(new GremlinServer("localhost", 8182), graphsonReader, graphsonWriter);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f4d27754/docs/src/reference/gremlin-applications.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index 1a7de96..877c473 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -1293,6 +1293,7 @@ Gremlin-Console |PLAIN SASL (username/password) |3.0.0-incubating
 |Pluggable SASL |3.0.0-incubating
 |GSSAPI SASL (Kerberos) |3.3.0
 |Gremlin-Python |PLAIN SASL |3.2.2
+|Gremlin.Net |PLAIN SASL |3.2.7
 |Gremlin-Javascript |PLAIN SASL |3.3.0
 |=========================================================
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f4d27754/docs/src/reference/gremlin-variants.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc
index 994f77a..9764874 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -342,7 +342,8 @@ A traversal source can be spawned with `RemoteStrategy` from an empty `Graph`.
 [source,csharp]
 ----
 var graph = new Graph();
-var g = graph.Traversal().WithRemote(new DriverRemoteConnection(new GremlinClient(new GremlinServer("localhost", 8182))));
+var remoteConnection = new DriverRemoteConnection(new GremlinClient(new GremlinServer("localhost", 8182)));
+var g = graph.Traversal().WithRemote(remoteConnection);
 ----
 
 When a traversal from the `GraphTraversalSource` is iterated, the traversal’s `Bytecode` is sent over the wire via the registered
@@ -366,6 +367,48 @@ terminal/action methods off of `ITraversal`.
 * `ITraversal.ToSet()`
 * `ITraversal.Iterate()`
 
+=== Configuration
+
+The following sections describe how the Gremlin.Net driver can be configured.
+
+==== Gremlin Server
+
+The connection properties for the Gremlin.Net driver can be passed to the `GremlinServer` instance as keyword arguments:
+
+[width="100%",cols="3,10,^2",options="header"]
+|=========================================================
+|Key |Description |Default
+|hostname |The hostname that the driver will connect to. |localhost
+|port |The port on which Gremlin Server can be reached. |8182
+|enableSsl |Determines if SSL should be enabled or not. If enabled on the server then it must be enabled on the client. |false
+|username |The username to submit on requests that require authentication. |_none_
+|password |The password to submit on requests that require authentication. |_none_
+|=========================================================
+
+==== Connection Pool
+
+It is also possible to configure the `ConnectionPool` of the Gremlin.Net driver. These configuration options can be set as properties
+on the `ConnectionPoolSettings` instance that can be passed to the `GremlinClient`:
+
+[width="100%",cols="3,10,^2",options="header"]
+|=========================================================
+|Key |Description |Default
+|MinSize |The minimum size of the connection pool. This determines how many connections are initially created. |8
+|MaxSize |The maximum size of the connection pool. |128
+|WaitForConnectionTimeout |The timespan to wait for a connection when the maximum size is reached before timing out. A `TimeoutException` is thrown when no connection becomes available until this timeout is reached. |3 seconds.
+|=========================================================
+
+==== GraphSON Serialization
+
+The Gremlin.Net driver uses by default GraphSON 3.0 but it is also possible to use GraphSON 2.0 which can be necessary
+when the server does not support GraphSON 3.0 yet:
+
+[source,csharp]
+----
+var client = new GremlinClient(new GremlinServer("localhost", 8182), new GraphSON2Reader(),
+    new GraphSON2Writer(), GremlinClient.GraphSON2MimeType);
+----
+
 === Static Enums and Methods
 
 Gremlin has various tokens (e.g. `T`, `P`, `Order`, `Operator`, etc.) that are represented in Gremlin.Net as classes.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f4d27754/docs/src/upgrade/release-3.4.x.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.4.x.asciidoc b/docs/src/upgrade/release-3.4.x.asciidoc
index 73cbd08..72a42b0 100644
--- a/docs/src/upgrade/release-3.4.x.asciidoc
+++ b/docs/src/upgrade/release-3.4.x.asciidoc
@@ -177,9 +177,9 @@ when dealing with that event. To make this easier, the event now raises with a `
 
 link:https://issues.apache.org/jira/browse/TINKERPOP-1831[TINKERPOP-1831]
 
-==== Gremlin.Net: Configurable Max and Min ConnectionPool Sizes
+==== Gremlin.Net Connection Pool
 
-Gremlin.Net's `ConnectionPool` now has a minimum and a maximum size. These sizes are configurable through added
+Gremlin.Net's `ConnectionPool` now has a minimum and a maximum size. These sizes are configurable through the newly added
 `ConnectionPoolSettings`. The minimum size determines how many connections are initially created. The maximum size
 is an upper limit of connections that can be created. When this limit is reached and another connection is needed,
 then the connection pool waits for a connection to become available again. The time to be waited is limited by the

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f4d27754/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPoolSettings.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPoolSettings.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPoolSettings.cs
index b156137..82b5edd 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPoolSettings.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPoolSettings.cs
@@ -47,7 +47,7 @@ namespace Gremlin.Net.Driver
         public int MaxSize { get; set; } = DefaultMaxPoolSize;
 
         /// <summary>
-        ///     Gets or sets the timespan to wait for a new connection before timing out.
+        ///     Gets or sets the timespan to wait for a connection to become available before timing out.
         /// </summary>
         /// <remarks>The default value is 3 seconds.</remarks>
         public TimeSpan WaitForConnectionTimeout { get; set; } = DefaultWaitForConnectionTimeout;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f4d27754/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs
index 601bbae..43ef159 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/GremlinServer.cs
@@ -38,7 +38,8 @@ namespace Gremlin.Net.Driver
         /// <param name="enableSsl">Specifies whether SSL should be enabled.</param>
         /// <param name="username">The username to submit on requests that require authentication.</param>
         /// <param name="password">The password to submit on requests that require authentication.</param>
-        public GremlinServer(string hostname, int port = 8182, bool enableSsl = false, string username = null, string password = null)
+        public GremlinServer(string hostname = "localhost", int port = 8182, bool enableSsl = false,
+            string username = null, string password = null)
         {
             Uri = CreateUri(hostname, port, enableSsl);
             Username = username;


[4/6] tinkerpop git commit: Added Huawei Graph Engine Service to listing - CTR

Posted by fl...@apache.org.
Added Huawei Graph Engine Service to listing - CTR


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

Branch: refs/heads/TINKERPOP-1774
Commit: 8f1fe6d8ebd753dc1fb708da53ba7a60354dbaf7
Parents: 69b6f96
Author: Robert Dale <ro...@gmail.com>
Authored: Wed Aug 1 22:33:57 2018 -0400
Committer: Robert Dale <ro...@gmail.com>
Committed: Wed Aug 1 22:33:57 2018 -0400

----------------------------------------------------------------------
 docs/site/home/index.html | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8f1fe6d8/docs/site/home/index.html
----------------------------------------------------------------------
diff --git a/docs/site/home/index.html b/docs/site/home/index.html
index 4ff692c..472e77a 100644
--- a/docs/site/home/index.html
+++ b/docs/site/home/index.html
@@ -224,6 +224,7 @@ limitations under the License.
             <li><a href="https://grakn.ai/">GRAKN.AI</a> - Distributed OLTP/OLAP knowledge graph system.</li>
             <li><a href="http://tinkerpop.apache.org/docs/current/reference/#sparkgraphcomputer">Hadoop (Spark)</a> - OLAP graph processor using Spark.</li>
             <li><a href="https://github.com/rayokota/hgraphdb">HGraphDB</a> - OLTP graph database running on Apache HBase.</li>
+            <li><a href="https://www.huaweicloud.com/en-us/product/ges.html">Huawei Graph Engine Service</a> - Fully-managed, distributed, at-scale graph query and analysis service that provides a visualized interactive analytics platform.</li>
             <li><a href="https://console.ng.bluemix.net/catalog/services/ibm-graph/">IBM Graph</a> - OLTP graph database as a service.</li>
             <li><a href="http://janusgraph.org/">JanusGraph</a> - Distributed OLTP and OLAP graph database with BerkeleyDB, Apache Cassandra and Apache HBase support.</li>
             <li><a href="https://github.com/awslabs/dynamodb-janusgraph-storage-backend//">JanusGraph (Amazon)</a> - The Amazon DynamoDB Storage Backend for JanusGraph.</li>