When I use gremlin-server connection using gremlin-driver in Java, I am not able to use "sideEffect" of GraphTraversal.

graph = EmptyGraph.instance()
cluster = Cluster.open("conf/remote-objects.yaml");
graphTraversalSource = graph.traversal().withRemote(DriverRemoteConnection.using(cluster));

My query that uses sideEffect looks like:

AtomicLong level1 = new AtomicLong(0);    
graphTraversalSource.V().hasLabel("user")
            .has("uuid", "1234")
            .sideEffect(it -> it.get().property("level", level1.getAndIncrement())).emit().repeat(in())
            .until(loops().is(5)).valueMap("uuid", "name", "level");

This query used to work when I was using janusgraph-dynamodb-storage-backend as dependency and running gremlin server within Java application and connecting to dyamodb. When i switched to using remote connection to gremlin server running in EC2, i started getting below error message:

java.util.concurrent.CompletionException: io.netty.handler.codec.EncoderException: WebSocketGremlinRequestEncoder must produce at least one message., took 3.895 sec

If I remove the sideEffect part from the above query, it works fine. I really need to add a custom property during traversal and include that in results without saving it in the database.

1

There are 1 answers

2
stephen mallette On

You have a few problems. The first problem is that you are trying to remote a lambda in the sideEffect() Lambdas can't be serialized to Gremlin bytecode - at least not in the form you've provided. However, you can do this:

gremlin> cluster = Cluster.open("conf/remote-objects.yaml")
==>localhost/127.0.0.1:8182
gremlin> g = graph.traversal().withRemote(DriverRemoteConnection.using(cluster))
==>graphtraversalsource[emptygraph[empty], standard]
gremlin> g.addV('person').as('p').addE('link').to('p')
==>e[1][0-link->0]
gremlin> g.V().sideEffect(Lambda.function("it.get().property('level',1)")).valueMap()
==>[level:[1]]

Note that I had to import import org.apache.tinkerpop.gremlin.util.function.* to the console to make that last line work there - That will be fixed for 3.2.7/3.3.0.

So, you could pass your lambda that way, but:

  1. I don't think your traversal will work as before because you are referencing a variable local to the client with level1 - the server is not going to know anything about that.
  2. TinkerPop generally recommends that you avoid lambdas.

I don't quite follow what your Gremlin is doing to provide a suggestion on how to resolve this. You do give this hint:

I really need to add a custom property during traversal and include that in results without saving it in the database.

...but the Gremlin above does write the value of level1 to the database so I'm not sure of what you are after.