【问题标题】:Multiple processes wait for the same Future to complete (scala)多个进程等待同一个 Future 完成(scala)
【发布时间】:2017-08-03 15:09:42
【问题描述】:

我现在没有直接使用它,但这个问题只是在我脑海中弹出,无法在网上找到一个好的答案:

我有一个函数“callExactKeyFromDB”,它返回:Either[A, Future[A]](A= 来自内存缓存中的本地,Future[A] = 查询数据库)。我可以将该 Future 传递给不同的线程/执行上下文,并让它们都在“onComplete”上注册,还是每次调用这个函数时我都返回一个新的未来,保留一个注册的未来列表并在我完成它们时更好可以。

现在的问题是我可以用 1 Future 做吗?我应该做吗?

(假设有 4 个进程从数据库请求用户信息并等待它继续)

【问题讨论】:

  • 1) 您可以撰写Futures,例如List[Future]Future[List] 但你是否应该是另一回事。 2)发布代码以将所有内容置于上下文中。

标签: scala concurrency future


【解决方案1】:

是的,您可以使用单个 Future 注册多个回调。这需要更少的代码、更少的内存,并且更具可读性。

【讨论】:

    【解决方案2】:

    我会摆脱 Either[A,Future[A]] 并将其转换为 Future[A] 开始。

    def getUserByKey(key:Int) : Future[User] =
      cache.users.contains(key) match {
        case true  => Future(cache.users(key))
        case false => Future(User(key = 101, name = "John Doe")) // db call
      }
    

    我想这会让事情变得更简单......

    如果cache 在上下文之间共享,则一旦保存,就无需多次调用数据库来获取该特定用户。

    def saveUserCache(u:User) : Future[Unit] = Future{
      cache.users.contains(u.key) match {
        case true  => cache.users(u.key) = u
        case false => cache.users += (u.key -> u)
      }
    }
    

    然后可以混合这些期货创造其他期货

    def renderUser(key:Int) : Future[String] =
      for {
        user   : User    <-  getUserByKey(key)
        update : Unit    <-  saveUserCache(user)
        output : String  <-  Future(s"${user.key}: ${user.name}")
      } yield output
    

    这能回答你的问题吗?

    【讨论】:

    • 我明白你为什么想要摆脱 Either 但这里是权衡:如果我需要调用 next() 函数、模式匹配(甚至 2 ifs) 在 Either 上还是返回一个完整的未来?
    猜你喜欢
    • 1970-01-01
    • 2015-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 2016-09-09
    • 2017-09-30
    • 1970-01-01
    相关资源
    最近更新 更多