Search code examples
gremlintinkerpoptinkerpop3janusgraphgremlin-server

Leaking connection in JanusGraph/tinkerpop


I am connecting to janusGraph remotely via

cluster = Cluster.build()
                .addContactPoints(uri.split("\\|"))
                .port(port)
                .serializer(new GryoMessageSerializerV1d0(GryoMapper.build().addRegistry(JanusGraphIoRegistry.getInstance())))
                .maxConnectionPoolSize(poolSize)
                .maxContentLength(10000000)
                .create();
        gts = AnonymousTraversalSource
                .traversal()
                .withRemote(DriverRemoteConnection.using(cluster));

As gts is threadSafe, i keep gts in static context. Each thread usess the same object and none of the thread closes gts by calling gts.close() Each thread runs query, for ex: result = gts.V().has("foo","bar").valueMap().toList() I do not close either gts(graphTraversalSource) not graphTraversal object which is created by gts.V()

  • Should I close each graphTraversal Object created out of gts(graphTraversalSource).?
  • When should I close these objects?

Solution

  • For the GraphTraversalSource, the need to call close() is driven by the manner in which you construct the object (i.e. "gts" in your case). The javadocs on DriverRemoteConnection explain the requirements for close(). In your particular case, you pass the Cluster object that you constructed to DriverRemoteConnection.using() which implies that you wish to control the shutdown of the Cluster yourself and therefore calling GraphTraversalSource.close() will only close any Client instances that your GraphTraversalSource spawned to do its work. You would then be required to call Cluster.close() yourself to get a complete orderly shutdown and release of resources.

    Behavior for close() on a GraphTraversal spawned from a GraphTraversalSource, is a bit different depending on whether or not you are remoting or not. In your case, you are using a remote traversal and therefore should call close() to release side-effects on the server (if the traversal generated any). Whether your server gathers side-effects or not for later retrieval is dependent on your implementation but for the most agnostic code it may be best to always explicitly do that. Note that traversals spawned over non-remote (embedded) graph databases that are iterated to completion, such that hasNext() is false, will trigger a call to close() and release resources held by the graph. For example, calling iterate() will trigger a close() automatically.

    As a side note, support for collecting side-effects held on the server was removed from the TinkerPop protocol in 3.5.0 so that worry is going away - servers simply won't have side-effects held in memory anymore for later retrieval.