【问题标题】:Scala - How to use a Timer without blocking on Futures with Await.resultScala - 如何使用 Timer 而不用 Await.result 阻塞 Future
【发布时间】:2017-12-01 00:03:02
【问题描述】:

我有一个由akka-http 提供的 Rest API。在某些情况下,我需要从外部数据库 (Apache HBase) 获取数据,如果数据库传输数据的时间过长,我希望查询失败。

一种天真的方法是将调用包装在 Future 中,然后使用具有所需持续时间的 Await.result 阻止它。

import scala.concurrent.duration._
import scala.concurrent.{Await, Future}

object AsyncTest1 extends App {

  val future = Future {
    getMyDataFromDB()
  }

  val myData = Await.result(future, 100.millis)
}

这似乎是低效的,因为这个实现需要两个线程。有没有一种有效的方法来做到这一点?

我有另一个用例,我想并行发送多个查询,然后聚合结果,具有相同的延迟限制。

val future1 = Future {
    getMyDataFromDB1()
  }

  val future2 = Future {
    getMyDataFromDB2()
  }

  val foldedFuture = Future.fold(
    Seq(future1, future2))(MyAggregatedData)(myAggregateFunction)
  )

  val myData = Await.result(foldedFuture, 100.millis)

同样的问题,最有效的实现方式是什么?

感谢您的帮助

【问题讨论】:

    标签: scala concurrency


    【解决方案1】:

    一种解决方案是使用 Akka 的 after 函数,它可以让你传递一个持续时间,之后未来会抛出异常或任何你想要的。

    看看here。它演示了如何实现这一点。

    编辑: 我想我会在这里发布代码,以防将来链接被破坏:

    import scala.concurrent._
    import scala.concurrent.duration._
    import ExecutionContext.Implicits.global
    import scala.util.{Failure, Success}
    import akka.actor.ActorSystem
    import akka.pattern.after
    
    val system = ActorSystem("theSystem")
    
    lazy val f = future { Thread.sleep(2000); true }
    lazy val t = after(duration = 1 second, using = system.scheduler)(Future.failed(new TimeoutException("Future timed out!")))
    
    val fWithTimeout = Future firstCompletedOf Seq(f, t)
    
    fWithTimeout.onComplete {
       case Success(x) => println(x)
       case Failure(error) => println(error)
    }
    

    【讨论】:

    • 感谢您的帮助。这种方法比Await.result 更有效吗?我是的,你能解释一下为什么吗?感谢您的帮助
    • 是的,它比Await.result 更有效,因为它不会阻塞线程。如果 DB 调用在一段时间后失败,您希望获得异常,因此在上面的示例中,future 将在 1 秒或更短的时间内完成,您将获得结果或异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-15
    • 2011-08-04
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 2016-10-08
    • 2020-12-02
    相关资源
    最近更新 更多