Подтвердить что ты не робот

ListenableFuture для scala Будущее

Я пишу небольшую обертку scala вокруг java-библиотеки.

В java-библиотеке есть объект QueryExecutor, отображающий 2 метода:

  • выполнить (запрос): Результат
  • asyncExecute (query): ListenableFuture [Результат]

ListenableFuture в этом контексте - это один из библиотеки guava.

Я хочу, чтобы моя оболочка scala возвращала Future [Result] вместо java-объекта, но я не уверен, что это лучший способ реализовать это. Вот два решения, которые я придумал:

future {
  executor.execute(query)
}

и

val p = promise[Result]
val guavaFuture = executor.asyncExecute(query)

Futures.addCallback(guavaFuture, new FutureCallback[Result] {
  def onFailure(t: Throwable) {
    p.failure(t)
  }

  def onSuccess(result: Result) {
    p.success(result)
  }
})

p.future

Мне интересно, какой метод лучше. Моя интуиция заключается в том, что первая, возвращая Будущее, по-прежнему будет блокировать поток, в то время как вызов для выполнения ожидает ответа, второй выглядит так, будто он действительно не блокируется. Любой комментарий о плюсах/минусах каждого метода?

4b9b3361

Ответ 1

Второй вариант лучше, он сохраняет все асинхронным. но... вы можете сделать это лучше и отвлечь решение в шаблоне многократного использования:

implicit class RichListenableFuture[T](lf: ListenableFuture[T]) {
  def asScala: Future[T] = {
    val p = Promise[T]()
    Futures.addCallback(lf, new FutureCallback[T] {
      def onFailure(t: Throwable): Unit = p failure t
      def onSuccess(result: T): Unit    = p success result
    })
    p.future
  }    
}

Затем вы можете просто вызвать:

executor.asyncExecute(query).asScala