[英]Scala - How to use a Timer without blocking on Futures with Await.result
I have an Rest API provided by akka-http
. 我有一个由
akka-http
提供的Rest API。 In some cases I need to get data from an external database ( Apache HBase
), and I would like the query to fail if the database takes too long to deliver the data. 在某些情况下,我需要从外部数据库(
Apache HBase
)获取数据,如果数据库花费太长时间来传递数据,我希望查询失败。
One naïve way is to wrap the call inside a Future
and then block it with an Await.result
with the needed duration. 一种天真的方法是将调用包装在
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)
}
The seems to be inefficient as this implementation needs two threads. 由于此实现需要两个线程,因此似乎效率低下。 Is There an efficient way to do this ?
有一种有效的方法吗?
I have another use case where I want to send multiple queries in parallel and then aggregates the results, with the same delay limitation. 我有另一个用例,我想并行发送多个查询,然后聚合结果,具有相同的延迟限制。
val future1 = Future {
getMyDataFromDB1()
}
val future2 = Future {
getMyDataFromDB2()
}
val foldedFuture = Future.fold(
Seq(future1, future2))(MyAggregatedData)(myAggregateFunction)
)
val myData = Await.result(foldedFuture, 100.millis)
Same question here, what is the most efficient way to implement this ? 同样的问题,实现这个的最有效方法是什么?
Thanks for your help 谢谢你的帮助
One solution would be to use Akka's after
function which will let you pass a duration, after which the future throws an exception or whatever you want. 一种解决方案是使用Akka的
after
函数,它可以让你传递一个持续时间,之后将会抛出异常或任何你想要的东西。
Take a look here . 看看这里 。 It demonstrates how to implement this.
它演示了如何实现这一点。
EDIT: I guess I'll post the code here in case the link gets broken in future: 编辑:我想我会在这里发布代码,以防链接在将来被破坏:
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)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.