简体   繁体   English

如何从 akka 流源获取迭代器?

[英]How to get an iterator from an akka streams Source?

I'm trying to create a flow that I can consume via something like an Iterator .我正在尝试创建一个流程,我可以通过Iterator类的东西使用它。 I'm implementing a library that exposes an iterator-like interface, so that would be the simplest thing for me to consume.我正在实现一个公开类似迭代器接口的库,因此这对我来说是最简单的消费方式。

My graph designed so far is essentially a Source<Iterator<DataRow>> .到目前为止,我设计的图表本质上是一个Source<Iterator<DataRow>> One thing I see so far is to flatten it to Source<DataRow> and then use http://doc.akka.io/japi/akka/current/akka/stream/javadsl/StreamConverters.html#asJavaStream-- followed by https://docs.oracle.com/javase/8/docs/api/java/util/stream/BaseStream.html#iterator--到目前为止我看到的一件事是将它展平为Source<DataRow>然后使用http://doc.akka.io/japi/akka/current/akka/stream/javadsl/StreamConverters.html#asJavaStream--其次是https ://docs.oracle.com/javase/8/docs/api/java/util/stream/BaseStream.html#iterator--

But given that there will be lots potentially many rows, I'm wondering whether it would make sense to avoid the flattening step (at least within the akka streams context, I'm assuming there's some minor per-element overhead when passed via stages), or if there's a more direct way.但是考虑到可能会有很多行,我想知道避免展平步骤是否有意义(至少在 akka 流上下文中,我假设通过阶段传递时每个元素的开销很小) ,或者如果有更直接的方法。

Also, I'm curious how backpressure works in the created stream, especially the child Iterator;另外,我很好奇背压在创建的 stream 中是如何工作的,尤其是子迭代器; does it only buffer one element?它只缓冲一个元素吗?

Flattening Step 展平步骤

Flattening a Source<Iterator<DataRow>> to a Source<DataRow> does add some amount of overhead since you'll have to use flatMapConcat which does eventually create a new GraphStage . Source<Iterator<DataRow>>Source<DataRow>确实会增加一些开销,因为您必须使用flatMapConcat ,最终会创建一个新的GraphStage

However, if you have "many" rows then this separate stage may come in handy since it will provide concurrency for the flattening step. 但是,如果您有“许多”行,则此单独的阶段可能会派上用场,因为它将为扁平化步骤提供并发性。

Backpressure 背压

If you look at the code of StreamConverters.asJavaStream you'll see that there is a QueueSink that is spawning a Future to pull the next element from the akka stream and then doing an Await.result(nextElementFuture, Inf) to wait on the Future to complete so the next element can be forwarded to the java Stream. 如果查看StreamConverters.asJavaStream 的代码 ,您会看到有一个QueueSink生成了Future来从akka流中提取下一个元素,然后执行Await.result(nextElementFuture, Inf)以等待Future完成,以便可以将下一个元素转发到java流。

Answering your question: yes the child Iterator only buffers one element, but the QueueSink has a Future which may also have the next DataRow . 回答您的问题:是的,子Iterator仅缓冲一个元素,但是QueueSink具有Future,也可能具有下一个DataRow Therefore the javaStream & Iterator may have 2 elements buffered, on top of however much buffering is going on in your original akka Source . 因此,javaStream&Iterator可能缓冲了2个元素,但是在原始akka Source进行了很多缓冲。

Alternatively, you may implement an Iterator using prefixAndTail(1) under the hood for implementing hasNext and next .或者,您可以在幕后使用prefixAndTail(1)来实现 Iterator 以实现hasNextnext

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM