用流和多线程应用程序包装Neo4j查询

时间:2019-07-05 17:55:31

标签: java neo4j

我对一些将Neo4j查询(Java驱动程序)与流结合在一起的复杂代码感到迷茫。

问题是我将这样的方法放入了一些底层组件:

    public <T> Stream<T> queryToStream ( Function<CypherClient, Stream<T>> action )
    {
        CypherClient client = this.newClient ();
        try {
            client.begin ();
            return action
                .apply ( client )
                .onClose ( () -> { if ( client.isOpen () ) client.close (); } );
        }
        catch ( RuntimeException ex ) {
            if ( client != null && client.isOpen () ) client.close ();
            throw ex;
        }
    }

this.newClient()将一个新的Neo4j会话包装到我的对象中,client.begin()开始一个Neo4j事务(只读),client.close()关闭事务和会话。

原始代码为herehere

我正在尝试通过客户端中定义的操作使用该方法:

    protected Stream<Record> queryToStream ( String query, Value params )
    {
        this.checkOpen ();
        StatementResult cursor = params == null 
            ? this.tx.run ( query )
            : this.tx.run ( query, params )             
        ;

        Spliterator<Record> splitr = spliteratorUnknownSize ( cursor, Spliterator.IMMUTABLE );
        return StreamSupport.stream ( splitr, false );      
    }

我通过这种方式间接调用:

// findPaths() uses client.queryToStream() and wraps the result 
// into another stream that maps Neo4j Record objects to a stream
// of ONDEXEntity objects
Stream<List<ONDEXEntity> paths = cyProvider.queryToStream (
                    cyClient -> cyClient.findPaths ( ... "MATCH path= ... RETURN path LIMIT $l SKIP n", cypherParams )
                );
    ...
    paths.close();

所以,我的想法是我从较低级别返回一个流,以惰性方式扫描查询结果,然后我通过发送paths.close()关闭Neo4j事务,下划线{{1}截获了它} 方法。调用者是here(是的,我在此简化一个相当复杂的代码)。

问题是我以并行方式发出多个查询,并且很快出现错误,例如:目前没有可用的线程来满足此请求

我想知道:

  • 如果我做得对,
  • 如果可以简化上述方法(基本上是关于并行查询+流包装)。我读到有关async features的内容,但并不太清楚。
  • 如果我需要控制并行度(在其中一些结束并关闭其事务之前要发送多少个查询),如果可以,那么如何做到(即,如何知道该限制是什么)服务器?)。

0 个答案:

没有答案