超时后停止fs2流

时间:2019-05-16 08:52:05

标签: scala fs2

我想使用类似于take(n: Int)的函数,但要在时间范围内: consume(period: Duration。因此,如果发生超时,我希望流终止。我知道我可以将流编译为IO[List[T]]之类并取消它,但是那样我会丢失结果。实际上,我想将无休止的流转换成有限的流并保留结果。

更多有关问题的更广泛范围。我有来自消息传递代理的无尽事件流,但是我也有轮换凭证来连接到代理。因此,我要消耗一段时间的事件流,然后停止,获取新的凭据,再次连接到代理以创建新的流,并将两个流连接为一个。

2 个答案:

答案 0 :(得分:1)

您需要类似的东西

  import scala.util.Random
  import scala.concurrent.ExecutionContext
  import fs2._
  import fs2.concurrent.SignallingRef
  implicit val ex = ExecutionContext.global
  implicit val t: Timer[IO] = IO.timer(ex)
  implicit val cs: ContextShift[IO] = IO.contextShift(ex)

  val effect: IO[Long] = IO.sleep(1.second).flatMap(_ => IO{
  val next = Random.nextLong()
  println("NEXT: " + next)
  next
 })
 val signal = SignallingRef[IO, Boolean](false).unsafeRunSync()
 val timer = Stream.sleep(10.seconds).flatMap(_ => 
 Stream.eval(signal.set(true)).flatMap(_ => 
 Stream.emit(println("Finish")).covary[IO]))

 val stream = timer concurrently 
 Stream.repeatEval(effect).interruptWhen(signal)

 stream.compile.drain.unsafeRunSync()

此外,如果要保存发布数据的结果,则需要从fs2获得一些无限制的Queue,以便通过queue.stream将发布的数据转换为结果。

答案 1 :(得分:1)

有一种方法可以做到这一点:

/**
    * Interrupts this stream after the specified duration has passed.
    */
  def interruptAfter[F2[x] >: F[x]: Concurrent: Timer](duration: FiniteDuration): Stream[F2, O]