Akka Streams:连接初始化资源的流

时间:2018-05-10 09:10:53

标签: scala akka-stream

我有两个流: A B

  • A 正在将文件写入磁盘并在执行期间附加其元素。
  • B 正在读取该文件并对数据进行一些处理。

仅在 A 完成处理并将其数据写入文件后,我想从 B 开始。

我尝试concat两个流:

A.concat(
  Source.lazily { () =>
    println("B is getting initialised")
    getStreamForB()
  }
)

但是这已经在 A 完成之前初始化 B

2 个答案:

答案 0 :(得分:4)

有一个ticket跟踪Source#concat不支持延迟实现的事实。该票提到了以下解决方法:

implicit class SourceLazyOps[E, M](val src: Source[E, M]) {
  def concatLazy[M1](src2: => Source[E, M1]): Source[E, NotUsed] =
    Source(List(() => src, () => src2)).flatMapConcat(_())
}

将上述隐式类应用于您的案例:

A.concatLazy(
  Source.lazily { () =>
    println("B is getting initialised")
    getStreamForB()
  }
)

答案 1 :(得分:1)

FileIO.toPath方法会将流实现为os.listdir。如果您正在使用正在写入文件的流Traceback (most recent call last): File "resize.py", line 10, in <module> print (img.shape) AttributeError: 'NoneType' object has no attribute 'shape'

Future[IOResult]

完成撰写后,您可以使用具体化的Future来启动您的信息流A

val someDataSource : Source[ByteString, _] = ???

val filePath : Path = ???

val fileWriteOptions : Set[OpenOption] = ???

val A : Future[IOResult] = 
  someDataSource
    .to(FileIO.toPath(filePath, fileWriteOptions))
    .run()

同样,在进行阅读之前,您可以对B进行一些测试,以确保在写入过程中没有失败:

val fileReadOptions : Set[OpenOption] = ???

val someProcessingWithTheDataOfB : Sink[ByteString, _] = ???

A foreach { _ =>

  val B : Future[IOResult] = 
    FileIO
      .fromPath(filePath, fileReadOptions)
      .to(someProcessingWithTheDataOfB)
      .run()
}