You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by xi...@apache.org on 2024/11/15 20:35:59 UTC

(tinkerpop) 01/01: CTR make bulked result default for remote traversal via DRC and updated relevant docs

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

xiazcy pushed a commit to branch bulked-default
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 15c5b36f0a7f85c5e3b4b092d8f46a610440781f
Author: Yang Xia <55...@users.noreply.github.com>
AuthorDate: Thu Nov 14 22:31:23 2024 -0800

    CTR make bulked result default for remote traversal via DRC and updated relevant docs
---
 docs/src/upgrade/release-4.x.x.asciidoc            | 24 ++++++++++++++++++++++
 .../tinkerpop/gremlin/driver/RequestOptions.java   |  6 ++++--
 .../driver/driver_remote_connection.py             |  3 +++
 .../src/main/python/tests/driver/test_client.py    |  9 ++++----
 .../tests/driver/test_driver_remote_connection.py  |  4 +++-
 5 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/docs/src/upgrade/release-4.x.x.asciidoc b/docs/src/upgrade/release-4.x.x.asciidoc
index d24a1a6e3b..3e43363fa3 100644
--- a/docs/src/upgrade/release-4.x.x.asciidoc
+++ b/docs/src/upgrade/release-4.x.x.asciidoc
@@ -30,6 +30,30 @@ complete list of all the modifications that are part of this release.
 
 === Upgrading for Users
 
+==== Result Bulking from Server
+In previous versions, when a traversal is submitted through the DriverRemoteConnection (DRC) via the Bytecode processor,
+the results from the server were bulked as Traverser, which provides a form of result optimization across the wire.
+Starting with 4.0, with the removal of Bytecode and Traverser serializer, this optimization is now achieved via
+`GraphBinaryV4` response message serialization, and can be controlled through cluster setting or per request option.
+
+Per request option setting will always override cluster settings, and regardless of cluster or request option settings,
+bulking will only occur if the script processing language is set to `gremlin-lang` and the serializer is set to `GraphBinaryV4`.
+
+[source,java]
+----
+// cluster setting
+Cluster cluster = Cluster.build().enableBulkedResult(true).create();
+
+// per request option
+GraphTraversalSource g = traversal().with(DriverRemoteConnection.using(cluster));
+List result = g.with("language", "gremlin-lang").with("bulked", true).inject(1).toList();
+----
+
+By default, the cluster setting for bulked result is false. To remain consistent with previous behavior, remote traversal
+submitted through the DRC will always send a request option setting `bulked` to `true`. This implies that if `gremlin-lang`
+script engine and `GraphBinaryV4` serializer are used, then results from the server will be bulked regardless of cluster setting,
+and can only be disabled via per request option.
+
 ==== BulkSet Behavior Changes
 Starting with 4.0, steps which return BulkSet (e.g. `aggregate()`) will have results returned in different format
 depending on embedded or remote usage.
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/RequestOptions.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/RequestOptions.java
index f5e8fcfef9..d3298e48a5 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/RequestOptions.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/RequestOptions.java
@@ -105,8 +105,10 @@ public final class RequestOptions {
                 builder.language((String) options.get(ARGS_LANGUAGE));
             if (options.containsKey(BULKED))
                 builder.withBulkedResult((boolean) options.get(BULKED));
-
         }
+        // request the server to send bulked results by default when using drc through request options
+        if (builder.bulkedResult == null)
+            builder.withBulkedResult(true);
 
         final Map<String, Object> parameters = gremlinLang.getParameters();
         if (parameters != null && !parameters.isEmpty()) {
@@ -122,7 +124,7 @@ public final class RequestOptions {
         private Long timeout = null;
         private String materializeProperties = null;
         private String language = null;
-        private String bulkedResult;
+        private String bulkedResult = null;
 
         /**
          * The aliases to set on the request.
diff --git a/gremlin-python/src/main/python/gremlin_python/driver/driver_remote_connection.py b/gremlin-python/src/main/python/gremlin_python/driver/driver_remote_connection.py
index b32d8f7ad0..da88ab88fc 100644
--- a/gremlin-python/src/main/python/gremlin_python/driver/driver_remote_connection.py
+++ b/gremlin-python/src/main/python/gremlin_python/driver/driver_remote_connection.py
@@ -123,6 +123,9 @@ class DriverRemoteConnection(RemoteConnection):
         for os in gremlin_lang.options_strategies:
             request_options.update({token: os.configuration[token] for token in Tokens
                                     if token in os.configuration})
+        # request the server to send bulked results by default when using drc through request options
+        if 'bulked' not in request_options:
+            request_options['bulked'] = True
         if gremlin_lang.parameters is not None and len(gremlin_lang.parameters) > 0:
             request_options["params"] = gremlin_lang.parameters
 
diff --git a/gremlin-python/src/main/python/tests/driver/test_client.py b/gremlin-python/src/main/python/tests/driver/test_client.py
index 4b6a9ad11b..462d40288a 100644
--- a/gremlin-python/src/main/python/tests/driver/test_client.py
+++ b/gremlin-python/src/main/python/tests/driver/test_client.py
@@ -23,7 +23,6 @@ import uuid
 
 import pytest
 from gremlin_python.driver.client import Client
-from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
 from gremlin_python.driver.protocol import GremlinServerError
 from gremlin_python.driver.request import RequestMessage
 from gremlin_python.driver.serializer import GraphBinarySerializersV4
@@ -266,7 +265,7 @@ def test_client_gremlin_lang_request_options_with_binding(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     # Note that bindings for constructed traversals is done via Parameter only
     t = g.with_('language', 'gremlin-lang').V(Parameter.var('x', [1, 2, 3])).count()
-    request_opts = DriverRemoteConnection.extract_request_options(t.gremlin_lang)
+    request_opts = {'language': 'gremlin-lang', 'params': {'x': [1, 2, 3]}}
     message = create_basic_request_message(t)
     result_set = client.submit(message, request_options=request_opts)
     assert result_set.all().result()[0] == 3
@@ -381,7 +380,7 @@ def test_multi_thread_pool(client):
 def test_client_gremlin_lang_with_short(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.with_('language', 'gremlin-lang').V().has('age', short(16)).count()
-    request_opts = DriverRemoteConnection.extract_request_options(t.gremlin_lang)
+    request_opts = {'language': 'gremlin-lang'}
     message = create_basic_request_message(t)
     result_set = client.submit(message, request_options=request_opts)
     results = []
@@ -393,7 +392,7 @@ def test_client_gremlin_lang_with_short(client):
 def test_client_gremlin_lang_with_long(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.V().has('age', long(851401972585122)).count()
-    request_opts = DriverRemoteConnection.extract_request_options(t.gremlin_lang)
+    request_opts = {}
     message = create_basic_request_message(t)
     result_set = client.submit(message, request_options=request_opts)
     results = []
@@ -405,7 +404,7 @@ def test_client_gremlin_lang_with_long(client):
 def test_client_gremlin_lang_with_bigint(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.with_('language', 'gremlin-lang').V().has('age', bigint(0x1000_0000_0000_0000_0000)).count()
-    request_opts = DriverRemoteConnection.extract_request_options(t.gremlin_lang)
+    request_opts = {'language': 'gremlin-lang'}
     message = create_basic_request_message(t)
     result_set = client.submit(message, request_options=request_opts)
     results = []
diff --git a/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection.py b/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection.py
index 86d6445316..ccc48e45d6 100644
--- a/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection.py
+++ b/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection.py
@@ -108,7 +108,8 @@ class TestDriverRemoteConnection(object):
         g = traversal().with_(remote_connection)
         t = g.with_("evaluationTimeout", 1000).with_("batchSize", 100).V().count()
         assert remote_connection.extract_request_options(t.gremlin_lang) == {'batchSize': 100,
-                                                                             'evaluationTimeout': 1000}
+                                                                             'evaluationTimeout': 1000,
+                                                                             'bulked': True}
         assert 6 == t.to_list()[0]
 
     def test_extract_request_options_with_params(self, remote_connection):
@@ -119,6 +120,7 @@ class TestDriverRemoteConnection(object):
         assert remote_connection.extract_request_options(t.gremlin_lang) == {'batchSize': 100,
                                                                              'evaluationTimeout': 1000,
                                                                              'userAgent': 'test',
+                                                                             'bulked': True,
                                                                              'params': {'ids': [1, 2, 3]}}
         assert 3 == t.to_list()[0]