当前位置: 首页 > 知识库问答 >
问题:

Scala——如何通过Await.result使用定时器而不阻塞期货

范浩宕
2023-03-14

我有一个由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)

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

多谢你的帮忙

共有1个答案

桓信鸥
2023-03-14

一种解决方案是使用Akka的after函数,该函数将允许您传递一个持续时间,在该持续时间之后,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)
}
 类似资料:
  • 正在寻找将Flux转换为<code>列表 使用反应式编程,但graph ql期望

  • 我正在使用java Callable和ExecutorService执行计算: 我想让任务运行最多2分钟。但如果我打电话: 然后它就会立刻封锁!不要让我为其他任务分配超时,直到超时结束。 我可以用 但它返回的是未来列表,我不知道什么任务属于哪个未来。

  • 问题内容: 因此,我一直在做一些阅读工作,以了解如何通过用户按Enter键退出while循环,并且得出以下结论: 有办法整理吗?特别是“ if not line”和后面的“ else”看起来很凌乱。可以合并成一个吗?比使用“开关”更好的选择? 最初,如果我键入了一堆字符然后按回车键,它并没有停止循环。我将不得不再次按Enter。if组件和else组件用于对其进行设置,以使其在首次按下Enter键时

  • 问题内容: 到目前为止,我所看到的所有示例都涉及阻塞(通过运算符)获取结果。 我当前的方法涉及传递指向结构的指针: goroutine完成时会写的内容。然后,只要方便就可以进行检查。您有更好的选择吗? 我真正想要的是Qt风格的信号槽系统。我有一个预感,解决方案看起来几乎是微不足道的(有 很多 未开发的潜力),但是我对这种语言还不十分了解。 问题答案: 您可以使用“逗号,可以”模式(请参阅其页面上的

  • 我不确定为什么所有的线程都被阻塞了。我以为类只加载一次,以后就不需要带任何锁了。

  • Java Future对象用于获取由并行线程(执行器)执行的异步计算的结果。我们调用Future.get()方法并等待结果就绪。此示例显示了一种从Future检索结果的非阻塞方式。java实现java非阻塞未来。 在本例中,在并行执行完成后调用onSuccess()方法。问题在于onSuccess()方法未在主线程上运行。我想在主线程上执行onSuccess()方法。我怎样才能解决这个问题。谢谢