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 2015/05/04 22:18:53 UTC

[1/4] incubator-tinkerpop git commit: Remove Terminator message from Gremlin Server protocol.

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/master 65a1e417e -> a35b2f4cd


Remove Terminator message from Gremlin Server protocol.

Added a "no content" code and a code for "partial content".  In this way the stream termination is implied in the response itself.  Reduces object/message creation overall.


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

Branch: refs/heads/master
Commit: 85d9f48caa25570aba45c1f37ecab88842276ad7
Parents: 6b93fab
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Sun May 3 06:31:58 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Sun May 3 06:31:58 2015 -0400

----------------------------------------------------------------------
 .../tinkerpop/gremlin/driver/Handler.java       | 12 ++++--
 .../driver/message/ResponseStatusCode.java      | 12 ++++--
 .../gremlin/server/handler/IteratorHandler.java |  6 ++-
 .../handler/NioGremlinResponseEncoder.java      | 29 ++++----------
 .../handler/WsGremlinResponseEncoder.java       | 25 +++---------
 .../server/op/AbstractEvalOpProcessor.java      | 18 +++++++--
 .../server/GremlinServerIntegrateTest.java      | 42 ++++++++------------
 7 files changed, 64 insertions(+), 80 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85d9f48c/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java
index 2cbdd9a..88a1601 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java
@@ -46,7 +46,8 @@ class Handler {
         @Override
         protected void channelRead0(final ChannelHandlerContext channelHandlerContext, final ResponseMessage response) throws Exception {
             try {
-                if (response.getStatus().getCode() == ResponseStatusCode.SUCCESS) {
+                if (response.getStatus().getCode() == ResponseStatusCode.SUCCESS ||
+                        response.getStatus().getCode() == ResponseStatusCode.PARTIAL_CONTENT) {
                     final Object data = response.getResult().getData();
                     if (data instanceof List) {
                         // unrolls the collection into individual response messages to be handled by the queue
@@ -59,10 +60,13 @@ class Handler {
                         // since this is not a list it can just be added to the queue
                         pending.get(response.getRequestId()).add(response);
                     }
-                } else if (response.getStatus().getCode() == ResponseStatusCode.SUCCESS_TERMINATOR)
-                    pending.remove(response.getRequestId()).markComplete();
-                else
+                } else
                     pending.get(response.getRequestId()).markError(new ResponseException(response.getStatus().getCode(), response.getStatus().getMessage()));
+
+                // todo: should this go in finally? where is the catch?
+                // as this is a non-PARTIAL_CONTENT code - the stream is done
+                if (response.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT)
+                    pending.remove(response.getRequestId()).markComplete();
             } finally {
                 ReferenceCountUtil.release(response);
             }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85d9f48c/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java
index c25d784..b082248 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java
@@ -33,14 +33,20 @@ import java.util.stream.Stream;
  */
 public enum ResponseStatusCode {
     /**
-     * The server successfully processed a request.
+     * The server successfully processed a request to completion - there are no messages remaining in this stream.
      */
     SUCCESS(200),
 
     /**
-     * The server is terminating a result set successfully.
+     * The server processed the request but there is no result to return (e.g. an {@link Iterator} with no elements).
      */
-    SUCCESS_TERMINATOR(299),
+    NO_CONTENT(204),
+
+    /**
+     * The server successfully returned some content, but there is more in the stream to arrive - wait for a
+     * {@link #SUCCESS} to signify the end of the stream.
+     */
+    PARTIAL_CONTENT(206),
 
     /**
      * The request message was not properly formatted which means it could not be parsed at all or the "op" code was

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85d9f48c/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/IteratorHandler.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/IteratorHandler.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/IteratorHandler.java
index cdb7975..7076cd1 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/IteratorHandler.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/IteratorHandler.java
@@ -85,8 +85,9 @@ public class IteratorHandler extends ChannelOutboundHandlerAdapter {
                         // send back a page of results if batch size is met or if it's the end of the results being
                         // iterated
                         if (aggregate.size() == resultIterationBatchSize || !itty.hasNext()) {
+                            final ResponseStatusCode code = itty.hasNext() ? ResponseStatusCode.PARTIAL_CONTENT : ResponseStatusCode.SUCCESS;
                             ctx.writeAndFlush(ResponseMessage.build(requestMessage)
-                                    .code(ResponseStatusCode.SUCCESS)
+                                    .code(code)
                                     .result(aggregate).create());
                             aggregate = new ArrayList<>(resultIterationBatchSize);
                         }
@@ -110,7 +111,8 @@ public class IteratorHandler extends ChannelOutboundHandlerAdapter {
                         ctx.writeAndFlush(ResponseMessage.build(requestMessage).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT).statusMessage(errorMessage).create());
                     }
 
-                    ctx.writeAndFlush(ResponseMessage.build(requestMessage).code(ResponseStatusCode.SUCCESS_TERMINATOR).create());
+                    // todo: no need to write terminator anymore
+                    // ctx.writeAndFlush(ResponseMessage.build(requestMessage).code(ResponseStatusCode.PARTIAL_CONTENT).create());
                 });
             } finally {
                 ReferenceCountUtil.release(msg);

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85d9f48c/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/NioGremlinResponseEncoder.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/NioGremlinResponseEncoder.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/NioGremlinResponseEncoder.java
index 987217e..99a4167 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/NioGremlinResponseEncoder.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/NioGremlinResponseEncoder.java
@@ -51,27 +51,16 @@ public class NioGremlinResponseEncoder extends MessageToByteEncoder<ResponseMess
         final boolean useBinary = ctx.channel().attr(StateKey.USE_BINARY).get();
 
         try {
-            if (useBinary) {
-                if (responseMessage.getStatus().getCode().isSuccess())
-                    byteBuf.writeBytes(serializer.serializeResponseAsBinary(responseMessage, ctx.alloc()));
-                else {
-                    byteBuf.writeBytes(serializer.serializeResponseAsBinary(responseMessage, ctx.alloc()));
-                    final ResponseMessage terminator = ResponseMessage.build(responseMessage.getRequestId()).code(ResponseStatusCode.SUCCESS_TERMINATOR).create();
-                    byteBuf.writeBytes(serializer.serializeResponseAsBinary(terminator, ctx.alloc()));
-                    errorMeter.mark();
-                }
-            } else {
+            if (!responseMessage.getStatus().getCode().isSuccess())
+                errorMeter.mark();
+
+            if (useBinary)
+                byteBuf.writeBytes(serializer.serializeResponseAsBinary(responseMessage, ctx.alloc()));
+            else {
                 // the expectation is that the GremlinTextRequestDecoder will have placed a MessageTextSerializer
                 // instance on the channel.
                 final MessageTextSerializer textSerializer = (MessageTextSerializer) serializer;
-                if (responseMessage.getStatus().getCode().isSuccess())
-                    byteBuf.writeBytes(textSerializer.serializeResponseAsString(responseMessage).getBytes(UTF8));
-                else {
-                    byteBuf.writeBytes(textSerializer.serializeResponseAsString(responseMessage).getBytes(UTF8));
-                    final ResponseMessage terminator = ResponseMessage.build(responseMessage.getRequestId()).code(ResponseStatusCode.SUCCESS_TERMINATOR).create();
-                    byteBuf.writeBytes(textSerializer.serializeResponseAsString(terminator).getBytes(UTF8));
-                    errorMeter.mark();
-                }
+                byteBuf.writeBytes(textSerializer.serializeResponseAsString(responseMessage).getBytes(UTF8));
             }
         } catch (Exception ex) {
             errorMeter.mark();
@@ -83,13 +72,9 @@ public class NioGremlinResponseEncoder extends MessageToByteEncoder<ResponseMess
                     .code(ResponseStatusCode.SERVER_ERROR_SERIALIZATION).create();
             if (useBinary) {
                 byteBuf.writeBytes(serializer.serializeResponseAsBinary(error, ctx.alloc()));
-                final ResponseMessage terminator = ResponseMessage.build(responseMessage.getRequestId()).code(ResponseStatusCode.SUCCESS_TERMINATOR).create();
-                byteBuf.writeBytes(serializer.serializeResponseAsBinary(terminator, ctx.alloc()));
             } else {
                 final MessageTextSerializer textSerializer = (MessageTextSerializer) serializer;
                 byteBuf.writeBytes(textSerializer.serializeResponseAsString(error).getBytes(UTF8));
-                final ResponseMessage terminator = ResponseMessage.build(responseMessage.getRequestId()).code(ResponseStatusCode.SUCCESS_TERMINATOR).create();
-                byteBuf.writeBytes(textSerializer.serializeResponseAsString(terminator).getBytes(UTF8));
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85d9f48c/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsGremlinResponseEncoder.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsGremlinResponseEncoder.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsGremlinResponseEncoder.java
index 0d65380..9855401 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsGremlinResponseEncoder.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsGremlinResponseEncoder.java
@@ -54,6 +54,9 @@ public class WsGremlinResponseEncoder extends MessageToMessageEncoder<ResponseMe
         final Session session = ctx.channel().attr(StateKey.SESSION).get();
 
         try {
+            if (!o.getStatus().getCode().isSuccess())
+                errorMeter.mark();
+
             if (useBinary) {
                 final ByteBuf serialized;
 
@@ -63,14 +66,7 @@ public class WsGremlinResponseEncoder extends MessageToMessageEncoder<ResponseMe
                 else
                     serialized = session.getExecutor().submit(() -> serializer.serializeResponseAsBinary(o, ctx.alloc())).get();
 
-                if (o.getStatus().getCode().isSuccess())
-                    objects.add(new BinaryWebSocketFrame(serialized));
-                else {
-                    objects.add(new BinaryWebSocketFrame(serialized));
-                    final ResponseMessage terminator = ResponseMessage.build(o.getRequestId()).code(ResponseStatusCode.SUCCESS_TERMINATOR).create();
-                    objects.add(new BinaryWebSocketFrame(serializer.serializeResponseAsBinary(terminator, ctx.alloc())));
-                    errorMeter.mark();
-                }
+                objects.add(new BinaryWebSocketFrame(serialized));
             } else {
                 // the expectation is that the GremlinTextRequestDecoder will have placed a MessageTextSerializer
                 // instance on the channel.
@@ -84,14 +80,7 @@ public class WsGremlinResponseEncoder extends MessageToMessageEncoder<ResponseMe
                 else
                     serialized = session.getExecutor().submit(() -> textSerializer.serializeResponseAsString(o)).get();
 
-                if (o.getStatus().getCode().isSuccess())
-                    objects.add(new TextWebSocketFrame(true, 0, serialized));
-                else {
-                    objects.add(new TextWebSocketFrame(true, 0, serialized));
-                    final ResponseMessage terminator = ResponseMessage.build(o.getRequestId()).code(ResponseStatusCode.SUCCESS_TERMINATOR).create();
-                    objects.add(new TextWebSocketFrame(true, 0, textSerializer.serializeResponseAsString(terminator)));
-                    errorMeter.mark();
-                }
+                objects.add(new TextWebSocketFrame(true, 0, serialized));
             }
         } catch (Exception ex) {
             errorMeter.mark();
@@ -103,13 +92,9 @@ public class WsGremlinResponseEncoder extends MessageToMessageEncoder<ResponseMe
                     .code(ResponseStatusCode.SERVER_ERROR_SERIALIZATION).create();
             if (useBinary) {
                 objects.add(new BinaryWebSocketFrame(serializer.serializeResponseAsBinary(error, ctx.alloc())));
-                final ResponseMessage terminator = ResponseMessage.build(o.getRequestId()).code(ResponseStatusCode.SUCCESS_TERMINATOR).create();
-                objects.add(new BinaryWebSocketFrame(serializer.serializeResponseAsBinary(terminator, ctx.alloc())));
             } else {
                 final MessageTextSerializer textSerializer = (MessageTextSerializer) serializer;
                 objects.add(new TextWebSocketFrame(textSerializer.serializeResponseAsString(error)));
-                final ResponseMessage terminator = ResponseMessage.build(o.getRequestId()).code(ResponseStatusCode.SUCCESS_TERMINATOR).create();
-                objects.add(new TextWebSocketFrame(textSerializer.serializeResponseAsString(terminator)));
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85d9f48c/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
index e9c5039..876163c 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
@@ -23,6 +23,7 @@ import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.tinkerpop.gremlin.driver.Tokens;
 import org.apache.tinkerpop.gremlin.driver.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
+import org.apache.tinkerpop.gremlin.driver.message.ResponseStatus;
 import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
 import org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor;
 import org.apache.tinkerpop.gremlin.structure.T;
@@ -175,11 +176,16 @@ public abstract class AbstractEvalOpProcessor implements OpProcessor {
                     logger.warn(errorMessage);
                     ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT).statusMessage(errorMessage).create());
                 }
-            } else {
+            }
+
+            // todo: no need to terminate anymore - handled by error code
+            /*
+            else {
                 // since this is not an error we need to terminate.  termination for errors is handled in the
                 // ResponseEncoder
-                ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SUCCESS_TERMINATOR).create());
+                ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.PARTIAL_CONTENT).create());
             }
+            */
             return null;
         }, executor);
     }
@@ -200,6 +206,11 @@ public abstract class AbstractEvalOpProcessor implements OpProcessor {
         final Settings settings = context.getSettings();
         boolean warnOnce = false;
 
+        if (!itty.hasNext())
+            ctx.writeAndFlush(ResponseMessage.build(msg)
+                    .code(ResponseStatusCode.NO_CONTENT)
+                    .create());
+
         // timer for the total serialization time
         final StopWatch stopWatch = new StopWatch();
         stopWatch.start();
@@ -221,8 +232,9 @@ public abstract class AbstractEvalOpProcessor implements OpProcessor {
             // also check writeability of the channel to prevent OOME for slow clients.
             if (ctx.channel().isWritable()) {
                 if  (aggregate.size() == resultIterationBatchSize || !itty.hasNext()) {
+                    final ResponseStatusCode code = itty.hasNext() ? ResponseStatusCode.PARTIAL_CONTENT : ResponseStatusCode.SUCCESS;
                     ctx.writeAndFlush(ResponseMessage.build(msg)
-                            .code(ResponseStatusCode.SUCCESS)
+                            .code(code)
                             .result(aggregate).create());
 
                     aggregate = new ArrayList<>(resultIterationBatchSize);

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/85d9f48c/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index 1634443..1c1d37e 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@ -129,9 +129,8 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
             final String fatty = IntStream.range(0, 150).mapToObj(String::valueOf).collect(Collectors.joining());
             final String fattyX = "['" + fatty + "'] * " + resultCountToGenerate;
 
-            // don't allow the thread to proceed until all results are accounted for (add one to the expected
-            // count since there will be a terminating message to account for
-            final CountDownLatch latch = new CountDownLatch((resultCountToGenerate / batchSize) + 1);
+            // don't allow the thread to proceed until all results are accounted for
+            final CountDownLatch latch = new CountDownLatch(resultCountToGenerate / batchSize);
             final AtomicBoolean expected = new AtomicBoolean(false);
             final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
                     .addArg(Tokens.ARGS_BATCH_SIZE, batchSize)
@@ -164,7 +163,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
             final CountDownLatch latch = new CountDownLatch(1);
             final AtomicBoolean pass = new AtomicBoolean(false);
             client.submit(request, result -> {
-                if (result.getStatus().getCode() != ResponseStatusCode.SUCCESS_TERMINATOR) {
+                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
                     pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
                     latch.countDown();
                 }
@@ -187,7 +186,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
             final CountDownLatch latch = new CountDownLatch(1);
             final AtomicBoolean pass = new AtomicBoolean(false);
             client.submit(request, result -> {
-                if (result.getStatus().getCode() != ResponseStatusCode.SUCCESS_TERMINATOR) {
+                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
                     pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
                     latch.countDown();
                 }
@@ -206,7 +205,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
                     .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]").create();
 
             // set the latch to six as there should be six responses when you include the terminator
-            final CountDownLatch latch = new CountDownLatch(6);
+            final CountDownLatch latch = new CountDownLatch(5);
             client.submit(request, r -> latch.countDown());
 
             assertTrue(latch.await(1500, TimeUnit.MILLISECONDS));
@@ -221,7 +220,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
                     .addArg(Tokens.ARGS_BATCH_SIZE, 1).create();
 
             // should be 11 responses when you include the terminator
-            final CountDownLatch latch = new CountDownLatch(11);
+            final CountDownLatch latch = new CountDownLatch(10);
             client.submit(request, r -> latch.countDown());
 
             assertTrue(latch.await(1500, TimeUnit.MILLISECONDS));
@@ -235,7 +234,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
                     .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]").create();
 
             // should be 2 responses when you include the terminator
-            final CountDownLatch latch = new CountDownLatch(2);
+            final CountDownLatch latch = new CountDownLatch(1);
             client.submit(request, r -> latch.countDown());
 
             assertTrue(latch.await(30000, TimeUnit.MILLISECONDS));
@@ -250,6 +249,8 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
         try {
             // this should return "nothing" - there should be no exception
             assertNull(client.submit("g.V().has('name','kadfjaldjfla')").one());
+        } catch (Exception ex) {
+            ex.printStackTrace();
         } finally {
             cluster.close();
         }
@@ -405,22 +406,18 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
     }
 
     @Test
-    public void shouldEvalAndOnlyReturnTwoMessages() throws Exception {
+    public void shouldEvalAndReturnSuccessOnlyNoPartialContent() throws Exception {
         try (SimpleClient client = new WebSocketClient()) {
             final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
                     .addArg(Tokens.ARGS_GREMLIN, "10").create();
 
             // set the latch to two as there should be two responses when you include the terminator -
             // the error and the terminator
-            final CountDownLatch latch = new CountDownLatch(2);
+            final CountDownLatch latch = new CountDownLatch(1);
             final AtomicInteger messages = new AtomicInteger(0);
             final AtomicBoolean errorReceived = new AtomicBoolean(false);
-            final AtomicBoolean terminatorReceived = new AtomicBoolean(false);
             client.submit(request, r -> {
-                if (latch.getCount() == 2)
-                    errorReceived.set(r.getStatus().equals(ResponseStatusCode.SUCCESS));
-                else if (latch.getCount() == 1)
-                    terminatorReceived.set(r.getStatus().equals(ResponseStatusCode.SUCCESS_TERMINATOR));
+                errorReceived.set(r.getStatus().equals(ResponseStatusCode.SUCCESS));
                 latch.countDown();
                 messages.incrementAndGet();
             });
@@ -430,7 +427,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
             // make sure no extra message sneak in
             Thread.sleep(1000);
 
-            assertEquals(2, messages.get());
+            assertEquals(1, messages.get());
         }
     }
 
@@ -440,19 +437,12 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
             final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
                     .addArg(Tokens.ARGS_GREMLIN, "new String().doNothingAtAllBecauseThis is a syntax error").create();
 
-            // set the latch to two as there should be two responses when you include the terminator -
-            // the error and the terminator
-            final CountDownLatch latch = new CountDownLatch(2);
+            final CountDownLatch latch = new CountDownLatch(1);
             final AtomicInteger messages = new AtomicInteger(0);
             final AtomicBoolean errorReceived = new AtomicBoolean(false);
-            final AtomicBoolean terminatorReceived = new AtomicBoolean(false);
             client.submit(request, r -> {
-                if (latch.getCount() == 2)
-                    errorReceived.set(r.getStatus().equals(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION));
-                else if (latch.getCount() == 1)
-                    terminatorReceived.set(r.getStatus().equals(ResponseStatusCode.SUCCESS_TERMINATOR));
+                errorReceived.set(r.getStatus().equals(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION));
                 latch.countDown();
-                System.out.println("*******" + r);
                 messages.incrementAndGet();
             });
 
@@ -461,7 +451,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
             // make sure no extra message sneak in
             Thread.sleep(1000);
 
-            assertEquals(2, messages.get());
+            assertEquals(1, messages.get());
 
         }
     }


[4/4] incubator-tinkerpop git commit: Merge remote-tracking branch 'origin/master'

Posted by sp...@apache.org.
Merge remote-tracking branch 'origin/master'


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

Branch: refs/heads/master
Commit: a35b2f4cd897a424fc70f9095ef2c639e72fa673
Parents: 5f4f162 65a1e41
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Mon May 4 16:18:44 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon May 4 16:18:44 2015 -0400

----------------------------------------------------------------------
 README.asciidoc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------



[2/4] incubator-tinkerpop git commit: Update docs given the removal of terminator message in Gremlin Server protocol.

Posted by sp...@apache.org.
Update docs given the removal of terminator message in Gremlin Server protocol.


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

Branch: refs/heads/master
Commit: 622821bca5fa15f8e11f91152e86458796e0cc66
Parents: 85d9f48
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Mon May 4 08:29:10 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon May 4 08:29:10 2015 -0400

----------------------------------------------------------------------
 docs/src/gremlin-applications.asciidoc          | 30 +++++++++++++-------
 .../driver/message/ResponseStatusCode.java      | 11 ++-----
 2 files changed, 22 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/622821bc/docs/src/gremlin-applications.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/gremlin-applications.asciidoc b/docs/src/gremlin-applications.asciidoc
index bb84836..e876869 100644
--- a/docs/src/gremlin-applications.asciidoc
+++ b/docs/src/gremlin-applications.asciidoc
@@ -591,21 +591,29 @@ In this case the `ResponseMessage` returned to the client would look something l
 
 [source,js]
 ----
-{"result":{"data":[{"id":2,"label":"vertex","type":"vertex","properties":{"name":"vadas","age":27}}],
-           "meta":{}},
+{"result":{"data":[{"id": 2,"label": "person","type": "vertex","properties": [
+  {"id": 2, "value": "vadas", "label": "name"},
+  {"id": 3, "value": 27, "label": "age"}]},
+  ], "meta":{}},
  "requestId":"1d6d02bd-8e56-421d-9438-3bd6d0079ff1",
- "status":{"code":200,"attributes":{},"message":""}}
+ "status":{"code":206,"attributes":{},"message":""}}
 ----
 
-Gremlin Server is capable of streaming results such that additional responses will arrive over the WebSocket until the iteration of the result on the server is complete.  Each successful incremental message will have a `ResultCode` of 200. The response stream is always marked as "complete" by a terminating message.  The "terminator" will look like this:
+Gremlin Server is capable of streaming results such that additional responses will arrive over the websocket until the iteration of the result on the server is complete.  Each successful incremental message will have a `ResultCode` of `206`. Termination of the stream will be marked by a final `200` status code.  Note that all messages without a `206` represent terminating conditions for a request.  The following table details the various status codes that Gremlin Server will send:
 
-[source,js]
-{"result":{"data":null,
-           "meta":{}},
- "requestId":"1d6d02bd-8e56-421d-9438-3bd6d0079ff1",
- "status":{"code":299,"attributes":{},"message":""}}
-
-The `299` code signifies stream termination which means that all processing for the request `1d6d02bd-8e56-421d-9438-3bd6d0079ff1` is complete.  Please see the link:http://www.tinkerpop.com/javadocs/current/org/apache/tinkerpop/gremlin/driver/message/ResultCode.html[javadoc] for more information on the various `code` values that are available.
+[width="100%",cols="2,2,9",options="header"]
+|=========================================================
+|Code |Name |Description
+|200 |SUCCESS | The server successfully processed a request to completion - there are no messages remaining in this stream.
+|204 |NO CONTENT | The server processed the request but there is no result to return (e.g. an {@link Iterator} with no elements).
+|206 |PARTIAL CONTENT | The server successfully returned some content, but there is more in the stream to arrive - wait for a `SUCCESS` to signify the end of the stream.
+|498 |MALFORMED REQUEST | The request message was not properly formatted which means it could not be parsed at all or the "op" code was not recognized such that Gremlin Server could properly route it for processing.  Check the message format and retry the request.
+|499 |INVALID REQUEST ARGUMENTS |The request message was parseable, but the arguments supplied in the message were in conflict or incomplete. Check the message format and retry the request.
+|500 |SERVER ERROR |A general server error occurred that prevented the request from being processed.
+|597 |SCRIPT EVALUATION ERROR |The script submitted for processing evaluated in the `ScriptEngine` with errors and could not be processed.  Check the script submitted for syntax errors or other problems and then resubmit.
+|598 |SERVER TIMEOUT |The server exceeded one of the timeout settings for the request and could therefore only partially responded or did not respond at all.
+|599 |SERVER SERIALIZATION ERROR |The server was not capable of serializing an object that was returned from the script supplied on the request. Either transform the object into something Gremlin Server can process within the script or install mapper serialization classes to Gremlin Server.
+|=========================================================
 
 OpProcessors Arguments
 ^^^^^^^^^^^^^^^^^^^^^^

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/622821bc/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java
index b082248..09f2402 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseStatusCode.java
@@ -21,6 +21,7 @@ package org.apache.tinkerpop.gremlin.driver.message;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.stream.Stream;
 
@@ -67,20 +68,14 @@ public enum ResponseStatusCode {
     SERVER_ERROR(500),
 
     /**
-     * The remote {@link Traversal} submitted for processing evaluated in on the server with errors and could not be
-     * processed.
-     */
-    SERVER_ERROR_TRAVERSAL_EVALUATION(596),
-
-    /**
      * The script submitted for processing evaluated in the {@code ScriptEngine} with errors and could not be
      * processed.  Check the script submitted for syntax errors or other problems and then resubmit.
      */
     SERVER_ERROR_SCRIPT_EVALUATION(597),
 
     /**
-     * The server exceeded one of the timeout settings for the request and could therefore only partially respond
-     * or not respond at all.
+     * The server exceeded one of the timeout settings for the request and could therefore only partially responded
+     * or did not respond at all.
      */
     SERVER_ERROR_TIMEOUT(598),
 


[3/4] incubator-tinkerpop git commit: Merge remote-tracking branch 'origin/master' into gs-protocol

Posted by sp...@apache.org.
Merge remote-tracking branch 'origin/master' into gs-protocol


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

Branch: refs/heads/master
Commit: 5f4f162b899ea69b35234d48cda79629b969360b
Parents: 622821b f0cddfa
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Mon May 4 11:43:58 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon May 4 11:43:58 2015 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   2 +
 .../process/traversal/step/Profileable.java     |  31 ++++++
 .../traversal/step/sideEffect/ProfileStep.java  |   8 +-
 .../strategy/decoration/ElementIdStrategy.java  |  18 ++++
 .../traversal/util/ImmutableMetrics.java        |   9 +-
 .../gremlin/process/traversal/util/Metrics.java |   4 +-
 .../util/StandardTraversalMetrics.java          |  37 +++++--
 .../gremlin/structure/util/star/StarGraph.java  |   2 +
 .../conf/gremlin-server-modern-readonly.yaml    |  44 ++++++++
 .../scripts/generate-modern-readonly.groovy     |  24 +++++
 .../server/op/AbstractEvalOpProcessor.java      |   1 +
 .../traversal/step/sideEffect/ProfileTest.java  | 101 ++++++++++++++-----
 .../hadoop/structure/io/VertexWritable.java     |  10 +-
 .../io/graphson/GraphSONRecordReader.java       |  13 +--
 .../structure/io/gryo/GryoRecordReader.java     |  15 +--
 .../gremlin/hadoop/HadoopGraphProvider.java     |  10 +-
 16 files changed, 255 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/5f4f162b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------