Jestem w trakcie pisania małego opakowania scala wokół biblioteki Java.ListenableFuture to scala Future
Biblioteka Java ma QueryExecutor obiektu poddawanie 2 metodami:
- wykonanie (hasła): Wynik
- asyncExecute (zapytanie) ListenableFuture [wynik]
ListenableFuture w tym kontekście ten z biblioteki guawy.
Chcę, aby moje opakowanie scala zwróciło wartość Future [Result] zamiast obiektu java, ale nie jestem pewien, jaki jest najlepszy sposób na jego implementację. Tu są 2 rozwiązania wymyśliłem:
future {
executor.execute(query)
}
i
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
Zastanawiam się, która metoda jest najlepsza. Moją intuicją jest, że pierwsza, zwracając Przyszłość, będzie nadal blokować wątek, podczas gdy wywołanie wykonania czeka na odpowiedź, druga wygląda tak, jakby nie była blokowana. Wszelkie uwagi na temat zalet/wad każdej metody?
Załóżmy masz 4 procesory. W tym przypadku domyślny "ExecutionContext" składa się z 4 pracowników. Każde 'przyszłe {executor.execute (zapytanie)} blokuje 1 pracownika, więc 4" futures "całkowicie zablokuje twój program. Można utworzyć dodatkowe 'ExecutionContext' dla operacji blokowania, ale będzie trochę narzut. – senia
Dzięki @senia, tak właśnie myślałem. Pierwszy kod jest asynchronizowany z punktu widzenia wywołującego, ale nadal blokuje wątek Kontekstu Wykonania, podczas gdy drugi jest naprawdę niezablokowany (zakładając, że asyncExecute używa niezablokowania IO). Czuję, że jest to bardzo podstawowe pytanie, ale nie jestem obeznany z Obietnicami. – vptheron
Uważam, że jest to pomocne w podobnym (lub możliwym nawet identycznym) wymogu: https://github.com/eigengo/activator-akka-cassandra/blob/master/src/main/scala/core/cassandra.scala – Gavin