如何在scala中使用线程安全异步包装器包装库异步方法?

问题描述 投票:1回答:1

我正在使用一个库,该库的方法看起来像这样。

  trait LibraryDependency {
    /**
     * This method if called while previous future is not resolved will return a failed future
     * @return
     */
    def foo(): Future[Boolean]
  }

此处,如果foo()返回的前一个将来尚未完成,则方法foo()将返回失败的将来。由于无法修改特征库的实现,因此我尝试用自己的包装器将其包装,以提供所需的行为。

我需要的行为是,如果同时存在对foo()的调用,则其他期货也会阻塞,直到第一个期货解决。我试图做这样的事情。

  class ThreadSafeLibraryWrapper(delegate: LibraryDependency) extends LibraryDependency {
    private val lock: Object = new Object
    private implicit val ec: ExecutionContext = ExecutionContext.Implicits.global

    /**
     * This one will block the other concurrent calls to foo()
     * @return
     */
    override def foo(): Future[Boolean] = {
      val promise = Promise[Boolean]()

      lock.synchronized {
        val result = delegate.foo()
        promise.completeWith(result)

        result.onComplete { _ =>
          lock.notify()
        }

        lock.wait()
      }

      promise.future
    }
  }

我遇到以下问题,我不确定如何阻止正在调用此方法的线程,并完成原始的将来,并且我得到IllegalMonitorStateException

编辑:我已经通过使用Await解决了这个问题>

  class ThreadSafeLibraryWrapper(delegate: LibraryDependency) extends LibraryDependency {
    private val lock: Object = new Object
    private implicit val ec: ExecutionContext = ExecutionContext.Implicits.global

    /**
     * This one will block the other concurrent calls to foo()
     * @return
     */
    override def foo(): Future[Boolean] = Future {
      lock.synchronized {
        Await.result(delegate.foo(), Duration.Inf)
      }
    }
  }

我仍然不确定如何避免Await

我正在使用一个库,该库的方法看起来像这样。 trait LibraryDependency {/ ** *如果在未解决以前的将来的情况下调用此方法,则将返回一个...

scala concurrency locking
1个回答
0
投票

如果我正确理解了您的问题,则您的依赖项可以同时在Future上运行,因此,您希望使用包装器来限制对foo方法的访问,从而避免返回失败的将来。如果是这样,则看起来您需要排队下一个调用,直到上一个调用完成。好吧,我做了一些原型设计,希望对您有所帮助:

© www.soinside.com 2019 - 2024. All rights reserved.