如何使用Akka延迟一秒钟来限制期货

时间:2018-12-18 12:45:59

标签: scala akka akka-stream akka-http

我有URI列表,我希望每个URI之间间隔一秒钟。我该怎么办?

System.ArgumentException

3 个答案:

答案 0 :(得分:4)

您可以从URI列表中创建Akka流Source,然后throttle将每个URI转换为Future[Response]

def httpRequest(uri: String): Future[Response] = ???

val uris: List[String] = ???

val responses: Future[Seq[Response]] =
  Source(uris)
    .throttle(1, 1 second)
    .mapAsync(parallelism = 1)(httpRequest)
    .runWith(Sink.seq[Response])

答案 1 :(得分:1)

类似这样的东西:

  @tailrec
  def withDelay(
    uris: Seq[String], 
    delay: Duration = 1 second, 
    result: List[Future[Response]] = Nil,
  ): Seq[Future[Response]] = uris match {
     case Seq() => result.reversed
     case (head, tail@_*) => 
        val v = result.headOption.getOrElse(Future.successful(null))
          .flatMap { _ => 
            akka.pattern.after(delay, context.system.scheduler)(httpRequest(head))
          }
        withDelay(tail, delay, v :: result)
   }

这在第一次执行之前也有一个延迟,但是我希望,如果需要的话,如何清除它已经足够清楚了... 另一个警告是,这假设所有期货都成功。一旦失败,所有后续处理都将中止。 如果您需要其他行为,则可以将.flatMap替换为.transform或添加.recover等。

如果愿意,也可以用.foldLeft来写:

  uris.foldLeft(List.empty[Future[Response]]) { case (results, next) => 
    results.headOption.getOrElse(Future.successful(null))
      .flatMap { _ => 
        akka.pattern.after(delay, context.system.scheduler)(httpRequest(next))
      } :: results
  }.reversed

答案 2 :(得分:0)

akka流具有out of the box with the throttle function(考虑到您正在使用akka-http并为akka流添加了标签)