在Akka Streams中将Sink转换为Graph(SinkShape)?

时间:2018-10-30 18:58:15

标签: scala akka akka-stream

我有这样的东西:

implicit val system = ActorSystem("actorSystem")
implicit val materializer = ActorMaterializer()

val (ref: ActorRef, publisher: Publisher[(String, String, String)]) =
  Source.actorRef[(String, String, String)](bufferSize = 1000, OverflowStrategy.fail)
    .toMat(transferFTP(_))(Keep.both)
    .run()

def transferFTP(data: (String, String, String)): Sink[ByteString, Future[IOResult]] = {
  // ...
}

在我阅读的每个示例中,toMat()都使用Sink作为参数,但是编译器期望Graph[SinkShape[(String,String,String)], NotInferedMat2]

1 个答案:

答案 0 :(得分:3)

toMat确实需要SinkSink[(String, String, String), _]Graph[SinkShape[(String, String, String)], _](换句话说,前者是后者的子类)。问题之一是您传递的是Sink[ByteString, _]。此外,当您的Publisher[(String, String, String)]的物化值为Sink时,您期望的是Future[IOResult]

下面是一个类型对齐的示例,从而使编译器感到满意:

val tupleToByteString: ((String, String, String)) => ByteString = ???

val transferFTP: Sink[ByteString, Future[IOResult]] = ???

val (ref: ActorRef, sink: Future[IOResult]) =
  Source.actorRef[(String, String, String)](bufferSize = 1000, OverflowStrategy.fail)
    .via(Flow.fromFunction(tupleToByteString)) // alternatively: .map(tupleToByteString)
    .toMat(transferFTP)(Keep.both)
    .run()