WebSocketGremlinRequestEncoder必须至少生成一条消息 - 使用withRemote的janusgraph-dynamodb“sideEffect”不起作用

时间:2017-09-10 02:52:40

标签: java amazon-dynamodb gremlin titan janusgraph

当我在Java中使用gremlin-driver使用gremlin-server连接时,我无法使用GraphTraversal的“sideEffect”。

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

我使用sideEffect的查询看起来像:

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");

当我使用janusgraph-dynamodb-storage-backend作为依赖项并在Java应用程序中运行gremlin服务器并连接到dyamodb时,此查询曾经工作。当我切换到使用EC2中运行的gremlin服务器的远程连接时,我开始收到以下错误消息:

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

如果我从上面的查询中删除sideEffect部分,它可以正常工作。我真的需要在遍历期间添加自定义属性,并将其包含在结果中而不将其保存在数据库中。

1 个答案:

答案 0 :(得分:0)

你有一些问题。第一个问题是你试图远程将sideEffect() Lambda中的lambda序列化为Gremlin字节码 - 至少不是你提供的形式。但是,您可以这样做:

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]]

请注意,我必须将import org.apache.tinkerpop.gremlin.util.function.*导入控制台以使最后一行在那里工作 - 这将在3.2.7 / 3.3.0中得到修复。

所以,你可以这样传递你的lambda,但是:

  1. 我不认为您的遍历会像以前一样工作,因为您使用level1引用客户端本地变量 - 服务器不会对此有所了解。
  2. TinkerPop通常建议您避免使用lambda。
  3. 我不太关注你的Gremlin正在做的事情,提出如何解决这个问题的建议。你确实给出了这个提示:

      

    我真的需要在遍历期间添加自定义属性,并将其包含在结果中而不将其保存在数据库中。

    ...但上面的Gremlin会将level1的值写入数据库,所以我不确定你的目标是什么。