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/10/10 21:21:17 UTC
(tinkerpop) 02/02: add bulked as ctx attr to preserve state & added remote feature test for bulked config
This is an automated email from the ASF dual-hosted git repository.
xiazcy pushed a commit to branch graphbinary-bulked-response
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 7490784ae77b7565713080f49aeb6aa9fa9bd6db
Author: Yang Xia <55...@users.noreply.github.com>
AuthorDate: Thu Oct 10 14:21:08 2024 -0700
add bulked as ctx attr to preserve state & added remote feature test for bulked config
---
.../driver/handler/GremlinResponseHandler.java | 3 +-
.../handler/HttpGremlinResponseStreamDecoder.java | 5 +++
.../server/handler/HttpGremlinEndpointHandler.java | 7 +--
.../GraphBinaryLangBulkedRemoteFeatureTest.java | 51 ++++++++++++++++++++++
.../gremlin/driver/remote/RemoteWorld.java | 10 +++++
.../io.cucumber.core.backend.ObjectFactory | 1 +
6 files changed, 73 insertions(+), 4 deletions(-)
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/GremlinResponseHandler.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/GremlinResponseHandler.java
index b44e26bcc2..3dfd983481 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/GremlinResponseHandler.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/GremlinResponseHandler.java
@@ -74,8 +74,9 @@ public class GremlinResponseHandler extends SimpleChannelInboundHandler<Response
if ((null == statusCode) || (statusCode == HttpResponseStatus.OK)) {
final List<Object> data = response.getResult().getData();
+ final boolean bulked = (boolean) channelHandlerContext.channel().attr(AttributeKey.valueOf("isBulked")).get();
// unrolls the collection into individual results to be handled by the queue.
- if (response.getResult().isBulked()) {
+ if (bulked) {
for (Iterator<Object> iter = data.iterator(); iter.hasNext(); ) {
Object obj = iter.next();
long bulk = (long) iter.next();
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/HttpGremlinResponseStreamDecoder.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/HttpGremlinResponseStreamDecoder.java
index 5c8c38edf9..16400ad9e6 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/HttpGremlinResponseStreamDecoder.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/HttpGremlinResponseStreamDecoder.java
@@ -49,6 +49,7 @@ public class HttpGremlinResponseStreamDecoder extends MessageToMessageDecoder<De
private static final AttributeKey<HttpResponseStatus> RESPONSE_STATUS = AttributeKey.valueOf("responseStatus");
private static final AttributeKey<String> RESPONSE_ENCODING = AttributeKey.valueOf("responseSerializer");
private static final AttributeKey<Long> BYTES_READ = AttributeKey.valueOf("bytesRead");
+ private static final AttributeKey<Boolean> IS_BULKED = AttributeKey.valueOf("isBulked");
private final MessageSerializer<?> serializer;
private final long maxResponseContentLength;
@@ -62,6 +63,7 @@ public class HttpGremlinResponseStreamDecoder extends MessageToMessageDecoder<De
@Override
protected void decode(ChannelHandlerContext ctx, DefaultHttpObject msg, List<Object> out) throws Exception {
final Attribute<Boolean> isFirstChunk = ((AttributeMap) ctx).attr(IS_FIRST_CHUNK);
+ final Attribute<Boolean> isBulked = ((AttributeMap) ctx).attr(IS_BULKED);
final Attribute<HttpResponseStatus> responseStatus = ((AttributeMap) ctx).attr(RESPONSE_STATUS);
final Attribute<String> responseEncoding = ((AttributeMap) ctx).attr(RESPONSE_ENCODING);
@@ -95,6 +97,9 @@ public class HttpGremlinResponseStreamDecoder extends MessageToMessageDecoder<De
out.add(response);
} else {
final ResponseMessage chunk = serializer.readChunk(content, isFirstChunk.get());
+ if (isFirstChunk.get()){
+ isBulked.set(chunk.getResult().isBulked());
+ }
isFirstChunk.set(false);
out.add(chunk);
}
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
index e92ba8d5a0..c5b4f1f6e7 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
@@ -313,8 +313,10 @@ public class HttpGremlinEndpointHandler extends SimpleChannelInboundHandler<Requ
final Bindings mergedBindings = mergeBindingsFromRequest(context, new SimpleBindings(graphManager.getAsBindings()));
final Object result = scriptEngine.eval(message.getGremlin(), mergedBindings);
- final boolean bulking = Objects.equals(context.getChannelHandlerContext().channel().attr(StateKey.REQUEST_HEADERS).get().get(Tokens.BULKED), "true")
- || (args.containsKey(Tokens.BULKED) && (boolean) args.get(Tokens.BULKED));
+ final boolean bulking = ((Objects.equals(context.getChannelHandlerContext().channel().attr(StateKey.REQUEST_HEADERS).get().get(Tokens.BULKED), "true")
+ && result instanceof Traversal)
+ || (args.containsKey(Tokens.BULKED) && (boolean) args.get(Tokens.BULKED))
+ && Objects.equals(language, "gremlin-lang"));
if (bulking) {
// optimization for driver requests
@@ -421,7 +423,6 @@ public class HttpGremlinEndpointHandler extends SimpleChannelInboundHandler<Requ
// while waiting for the client to catch up
if (aggregate.size() < resultIterationBatchSize && itty.hasNext()) {
if (bulking) {
- // bulking will return
Traverser traverser = (Traverser) itty.next();
aggregate.add(traverser.get());
aggregate.add(traverser.bulk());
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/GraphBinaryLangBulkedRemoteFeatureTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/GraphBinaryLangBulkedRemoteFeatureTest.java
new file mode 100644
index 0000000000..1e5b0a7317
--- /dev/null
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/GraphBinaryLangBulkedRemoteFeatureTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+package org.apache.tinkerpop.gremlin.driver.remote;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Stage;
+import io.cucumber.guice.CucumberModules;
+import io.cucumber.junit.Cucumber;
+import io.cucumber.junit.CucumberOptions;
+import org.apache.tinkerpop.gremlin.features.AbstractGuiceFactory;
+import org.apache.tinkerpop.gremlin.features.World;
+import org.junit.runner.RunWith;
+
+@RunWith(Cucumber.class)
+@CucumberOptions(
+ tags = "not @RemoteOnly and not @GraphComputerOnly and not @AllowNullPropertyValues",
+ glue = { "org.apache.tinkerpop.gremlin.features" },
+ objectFactory = GraphBinaryLangBulkedRemoteFeatureTest.RemoteGuiceFactory.class,
+ features = { "classpath:/org/apache/tinkerpop/gremlin/test/features" },
+ plugin = {"progress", "junit:target/cucumber.xml"})
+public class GraphBinaryLangBulkedRemoteFeatureTest extends AbstractFeatureTest {
+ public static class RemoteGuiceFactory extends AbstractGuiceFactory {
+ public RemoteGuiceFactory() {
+ super(Guice.createInjector(Stage.PRODUCTION, CucumberModules.createScenarioModule(), new ServiceModule()));
+ }
+ }
+
+ public static final class ServiceModule extends AbstractModule {
+ @Override
+ protected void configure() {
+ bind(World.class).to(RemoteWorld.GraphBinaryLangBulkedRemoteWorld.class);
+ }
+ }
+}
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteWorld.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteWorld.java
index b1c66c1d39..84109b080e 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteWorld.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/RemoteWorld.java
@@ -169,6 +169,16 @@ public abstract class RemoteWorld implements World {
}
}
+ public static class GraphBinaryLangBulkedRemoteWorld extends RemoteWorld {
+ public GraphBinaryLangBulkedRemoteWorld() { super(createTestCluster(Serializers.GRAPHBINARY_V4)); }
+
+ @Override
+ public GraphTraversalSource getGraphTraversalSource(final LoadGraphWith.GraphData graphData) {
+ final GraphTraversalSource g = super.getGraphTraversalSource(graphData);
+ return g.with("language", "gremlin-lang").with("bulked", true);
+ }
+ }
+
public static class GraphBinaryGroovyRemoteWorld extends RemoteWorld {
public GraphBinaryGroovyRemoteWorld() { super(createTestCluster(Serializers.GRAPHBINARY_V4)); }
diff --git a/gremlin-server/src/test/resources/META-INF/services/io.cucumber.core.backend.ObjectFactory b/gremlin-server/src/test/resources/META-INF/services/io.cucumber.core.backend.ObjectFactory
index 5b6b888d13..7b70b113b0 100644
--- a/gremlin-server/src/test/resources/META-INF/services/io.cucumber.core.backend.ObjectFactory
+++ b/gremlin-server/src/test/resources/META-INF/services/io.cucumber.core.backend.ObjectFactory
@@ -1,3 +1,4 @@
org.apache.tinkerpop.gremlin.driver.remote.GraphBinaryLangRemoteFeatureTest$RemoteGuiceFactory
+org.apache.tinkerpop.gremlin.driver.remote.GraphBinaryLangBulkedRemoteFeatureTest$RemoteGuiceFactory
org.apache.tinkerpop.gremlin.driver.remote.GraphBinaryGroovyRemoteFeatureTest$RemoteGuiceFactory
org.apache.tinkerpop.gremlin.driver.remote.GraphBinaryRemoteComputerFeatureTest$RemoteGuiceFactory