并行运行多个 future,超时返回默认值

2023-12-30

我必须并行运行多个 future,并且程序不应崩溃或挂起。

现在,我一一等待 future,如果出现 TimeoutException,则使用后备值。

val future1 = // start future1
val future2 = // start future2
val future3 = // start future3

// <- at this point all 3 futures are running

// waits for maximum of timeout1 seconds
val res1 = toFallback(future1, timeout1, Map[String, Int]())
// .. timeout2 seconds 
val res2 = toFallback(future2, timeout2, List[Int]())
// ... timeout3 seconds
val res3 = toFallback(future3, timeout3, Map[String, BigInt]()) 

def toFallback[T](f: Future[T], to: Int, default: T) = {
  Try(Await.result(f, to seconds))
    .recover { case to: TimeoutException => default }
}

正如我所看到的,该片段的最大等待时间是timeout1 + timeout2 + timeout3

我的问题是:我怎样才能同时等待所有这些期货,这样我就可以减少等待时间max(timeout1, timeout2, timeout3)?

编辑:最后我使用了 @Jatin 和 @senia 答案的修改:

private def composeWaitingFuture[T](fut: Future[T], 
                                    timeout: Int, default: T) =
  future { Await.result(fut, timeout seconds) } recover {
    case e: Exception => default
  }

后来它的使用如下:

// starts futures immediately and waits for maximum of timeoutX seconds
val res1 = composeWaitingFuture(future1, timeout1, Map[String, Int]())
val res2 = composeWaitingFuture(future2, timeout2, List[Int]())
val res3 = composeWaitingFuture(future3, timeout3, Map[String, BigInt]()) 

// takes the maximum of max(timeout1, timeout2, timeout3) to complete
val combinedFuture =
  for {
    r1 <- res1
    r2 <- res2
    r3 <- res3
  } yield (r1, r2, r3)

后来我用combinedFuture我认为合适。


你可以创建future返回所有 3 个 future 的结果flatMap或用于理解:

val combinedFuture =
  for {
    r1 <- future1
    r2 <- future2
    r3 <- future3
  } yield (r1, r2, r3)

val (r1, r2, r3) = Await.result(combinedFuture , Seq(timeout1, timeout2, timeout3).max)

如果您正在使用akka您可以在超时后使用默认值完成您的未来:

implicit class FutureHelper[T](f: Future[T]) extends AnyVal{
  import akka.pattern.after
  def orDefault(t: Timeout, default: => T)(implicit system: ActorSystem): Future[T] = {
    val delayed = after(t.duration, system.scheduler)(Future.successful(default))
    Future firstCompletedOf Seq(f, delayed)
  }
}

val combinedFuture =
  for {
    r1 <- future1.orDefault(timeout1, Map())
    r2 <- future2.orDefault(timeout2, List())
    r3 <- future3.orDefault(timeout3, Map())
  } yield (r1, r2, r3)

val (r1, r2, r3) = Await.result(combinedFuture , allowance + Seq(timeout1, timeout2, timeout3).max)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

并行运行多个 future,超时返回默认值 的相关文章

随机推荐

  • 带有 MarkupExtension 的 IValueConverter

    最近我读到一篇关于IValueConverter它也继承自MarkupExtension 它是这样的 internal class BoolToVisibilityConverter MarkupExtension IValueConver
  • Android 日志记录 - 如何清除以获得更好的性能

    Android新手 刚刚看了http developer android com reference android util Log html http developer android com reference android ut
  • 如何打印随机数菱形?

    有人可以帮我完成这个数字钻石吗 我打印了钻石的右侧 但在打印左侧时遇到了问题 如果有人可以提供帮助 我将非常感激 我对我的代码做了一些更改 我现在需要我的代码在菱形中间打印一列而不是两列 public class NumericDiamon
  • while 循环在需要时未结束

    所以一些背景信息 我是编程新手 仍在学习 所以我为我犯的微不足道的错误道歉 我正在制作自己的基于文本的游戏只是为了进一步练习等 以下是 Dropbox 上所有内容的链接 以了解更多背景信息 https www dropbox com sh
  • Monad 变压器:IO 和状态

    这个问题与其他地方已经涵盖的问题很接近 但我还没有找到任何具体解决它的内容 至少不是以我能够理解的方式 我想以取决于各种随机选择的方式更新状态 由于我正在使用 RandomSource 类型类的实例 所有这些随机选择都存在于 IO mona
  • Android Fragment从共享ViewModel问题中收集SharedFlow

    目前我有一个ViewPager2片段 作为起始目的地 包含两个子片段 ActiveOrderFragment and CompletedOrderFragment 他们都有自己的ViewModel处理 api 调用 获取活动订单和已完成订单
  • 简单模板类的“未定义符号”链接器错误

    离开 C 几年了 我从以下代码中收到链接器错误 Gene h ifndef GENE H INCLUDED define GENE H INCLUDED template
  • 在64位Debian环境下编译32位qt源

    我想在 Debian 64 位环境上构建 32 位应用程序 因此 我正在尝试编译 Qt 源代码以获得 32 位库 我正在尝试使用以下配置命令 configure platform linux g 32 不幸的是 我收到如下错误 Basic
  • AngularJS 中的错误请求错误

    var successCallback function response if response success log log response data alert fetched courses and percentages su
  • 以编程方式清除 Chrome 浏览器历史记录

    我尝试过使用以下代码 但它不适用于 chrome 仅适用于旧浏览器 Browser clearHistory getContentResolver 这段代码对我有用 private void clearHistoryChrome Conte
  • 如何检测浏览器窗口是否滚动到底部?

    我需要检测用户是否滚动到页面底部 如果它们位于页面底部 当我向底部添加新内容时 我会自动将它们滚动到新底部 如果它们不在底部 则它们正在阅读页面上较高位置的先前内容 因此我不想自动滚动它们 因为它们想留在原处 如何检测用户是否滚动到页面底部
  • 启用 Sleuth 会减慢请求速度(很多)

    我将 Spring Cloud Feign 和 Sleuth 与 Zipkin 服务器结合使用 我的问题是 当我启用 Sleuth 时 任何简单的请求至少需要 600 毫秒 请注意 出于测试目的 我将 Sleuth 的采样器百分比设置为 1
  • http 代理背后的 PHP Composer

    我在网络上使用 Composer 其中访问互联网的唯一方法是使用 HTTP 或袜子代理 我有 http proxy 和 https proxy 环境变量 当 compose 尝试访问 HTTPS URL 时 我得到以下信息 file cou
  • Maven、Scala、Spring、AspectJ

    有谁知道是否可以在编译时使用aspectJ和spring编织scala类 我的编译时编织适用于我的所有 java 类 但我似乎无法让它适用于使用 Configurable 的 scala 类 作为背景 我已经为此工作了几天 多么痛苦啊 无论
  • shell 脚本中的“if [ -t 1 ]”有什么作用?

    我有将 zsh 设置为默认 shell 的代码 if t 1 then exec zsh fi 该命令具体执行什么操作if t 1 在这里做吗 我有将 zsh 设置为默认 shell 的代码 不 你没有 这不是你的代码所做的 尽管它产生了类
  • 通过 WebDAV 脚本为 NextCloud 文件添加标签

    我使用 NextCloud 11 来存储我的个人文件 并使用文档中的简单curl 脚本将文件上传到我的 NextCloud 驱动器 curl u user pw T test pdf http localhost nextcloud rem
  • 将 pdf 转换为 txt 文件的函数的输出重定向到 python 中的新文件夹

    我正在使用 python 3 我的代码使用 pdfminer 将 pdf 转换为文本 我想在新文件夹中获取这些文件的输出 目前它位于现有文件夹中 使用 pdfminer 从该文件夹转换为 txt 如何将输出重定向到不同的文件夹 我希望输出位
  • PHP $_Server 无法正常工作[重复]

    这个问题在这里已经有答案了 我有以下几行 div class social http SERVER HTTP HOST SERVER REQUEST URI div 一切都很棒 它显示了当前的链接 比方说 http www example
  • 重置 Android 文本视图最大行数

    我想制作一个可以通过用户触摸折叠的 TextView 当 TextView 折叠时 我设置textView setMaxLines 4 如何在扩展方法中清除此状态 我只能想到打电话setMaxLines 值很大 例如10000 有更好的方法
  • 并行运行多个 future,超时返回默认值

    我必须并行运行多个 future 并且程序不应崩溃或挂起 现在 我一一等待 future 如果出现 TimeoutException 则使用后备值 val future1 start future1 val future2 start fu