我需要使用以下界面创建一个函数:
import akka.kafka.scaladsl.Consumer.Control
object ItemConversionFlow {
def build(config: StreamConfig): Flow[Item, OtherItem, Control] = {
// Implementation goes here
}
我的问题是我不知道如何以适合上述界面的方式定义流程。
当我做这样的事情时
val flow = Flow[Item]
.map(item => doConversion(item)
.filter(_.isDefined)
.map(_.get)
结果类型是Flow [Item,OtherItem,NotUsed]。到目前为止,我还没有在Akka文档中找到一些东西。此外,akka.stream.scaladsl.Flow上的函数仅提供“NotUsed”而不是Control。如果有人能指出我正确的方向,那就太棒了。
一些背景知识:我需要设置几个仅在转换部分中区分的管道。这些管道是主流的子流,可能由于某种原因而停止(相应的消息到达某个kafka主题)。因此我需要控制部分。我的想法是创建一个Graph模板,我只需将上述流作为参数插入(工厂返回它)。对于特定情况,我们有一个有效的解决方案。为了概括它,我需要这种流程。
答案 0 :(得分:0)
你实际上有背压。但是,想想你对背压真正需要什么......例如,你没有使用异步阶段来提高吞吐量...... Backpressure避免了快速生产者过度生长的嫌疑人https://doc.akka.io/docs/akka/2.5/stream/stream-rate.html。在您的示例中不用担心,您的流将根据 doConversion 完成的时间长度向发布者请求新元素。
如果您想获取流的结果,请使用toMat或viaMat。例如,如果您的流发出Item并将其转换为OtherItem:
val str = Source.fromIterator(() => List(Item(Some(1))).toIterator)
.map(item => doConversion(item))
.filter(_.isDefined)
.map(_.get)
.toMat(Sink.fold(List[OtherItem]())((a, b) => {
// Examine the result of your stream
b :: a
}))(Keep.right)
.run()
str将是Future [List [OtherItem]]。试着根据你的情况推断这个。
或者使用toMat with KillSwitches,“创建一个[[FlowShape]]的新[[Graph]],它实现了一个允许外部完成的外部开关 *独特的物化。不同的实现会产生不同的独立开关。“
def build(config: StreamConfig): Flow[Item, OtherItem, UniqueKillSwitch] = {
Flow[Item]
.map(item => doConversion(item))
.filter(_.isDefined)
.map(_.get)
.viaMat(KillSwitches.single)(Keep.right)
}
val stream =
Source.fromIterator(() => List(Item(Some(1))).toIterator)
.viaMat(build(StreamConfig(1)))(Keep.right)
.toMat(Sink.ignore)(Keep.both).run
// This stops the stream
stream._1.shutdown()
// When it finishes
stream._2 onComplete(_ => println("Done"))