@Viktor Klang: Rozumiemy, że j.u.c.Future
jest obrzydliwością. Ale właśnie to otrzymujemy z oprogramowania, które musimy zaakceptować, jak na razie.
Jak dotąd, to co mamy hacked razem:
def wrapJavaFutureInAkkaFuture[T](javaFuture: java.util.concurrent.Future[T], maybeTimeout: Option[Duration] = None)(implicit system: ActorSystem): akka.dispatch.Future[T] = {
val promise = new akka.dispatch.DefaultPromise[T]
pollJavaFutureUntilDoneOrCancelled(javaFuture, promise, maybeTimeout.map(_.fromNow))
promise
}
Innymi słowy, należy utworzyć oddzielną Akka Promise
(write-boczny Future
) odpowiadający j.u.c.Future
, rozpoczyna wywołanie zwrotne pollJavaFutureUntilDoneOrCancelled
, aby zaktualizować Obietnicę przez sondowanie "obrzydliwości" i zwraca Obietnicę do osoby dzwoniącej.
Jak więc "odpytać", aby zaktualizować obietnicę Akka na podstawie stanu j.u.c.Future?
def pollJavaFutureUntilDoneOrCancelled[T](javaFuture: java.util.concurrent.Future[T], promise: akka.dispatch.Promise[T], maybeDeadline: Option[Deadline] = None)(implicit system: ActorSystem) {
if (maybeDeadline.exists(_.isOverdue)) javaFuture.cancel(true);
if (javaFuture.isDone || javaFuture.isCancelled) {
promise.complete(allCatch either { javaFuture.get })
} else {
Play.maybeApplication.foreach { implicit app =>
system.scheduler.scheduleOnce(50 milliseconds) {
pollJavaFutureUntilDoneOrCancelled(javaFuture, promise, maybeDeadline)
}
}
}
}
To jest próba tego, o czym była mowa w dyskusji grup dyskusyjnych, do której się odwoływałem w pytaniu. Używa programu planującego Akka do wywoływania siebie co 50 ms w celu sprawdzenia, czy j.u.c.Future zostało wykonane lub anulowane. Ilekroć tak się stanie, aktualizuje się obietnicę Akka z zakończonym stanem.
@Victor Klang, et al:
Jest to najlepsza praktyka? Czy znasz lepszy sposób na zrobienie tego? Czy brakuje nam tu minusów, o których powinniśmy wiedzieć?
Dzięki za pomoc.
Oczywistym minusem jest to, że w najgorszym wypadku może to spowodować duże opóźnienie odpowiedzi. Jeśli na przykład ustawienia domyślne i Twoja przyszłość zakończy się po 1 ms po sprawdzeniu, może to spowodować opóźnienie około 100ms. Można to jednak zmienić, ustawiając 'scheduler.Ustawienie "czasu trwania" w konfiguracji. – drexin
@drexin prawda, ale czas trwania tyknięcia i kompromis w zakresie częstotliwości sond będą obecne w każdym rozwiązaniu opartym na głosowaniu, prawda? –
Oczywiście, ale kiedy prosiłeś o wady, chciałem ci tylko powiedzieć, że zależy to nie tylko od opóźnienia paramu wywołania 'scheduleOnce', ale także od ustawienia w konfiguracji akka. Jeśli możesz żyć z opóźnieniem, powinno to być użyteczne rozwiązanie. – drexin