traduccion spanish juice fruta examples espaƱol java guava

java - spanish - guava maven



ListenableFuture, FutureCallback y tiempos de espera (1)

Basado en los ejemplos de guayaba que he visto, he estado buscando soluciones elegantes para mi problema. Específicamente, me gusta la forma en que funciona Futures.addCallback(ListenableFuture, FutureCallback) , pero me gustaría poder establecer un tiempo de espera sobre el tiempo que puede expirar antes de que se invoque FutureCallback. Óptimo Sería bueno si incumplir el tiempo de espera solo causara que se llame a la condición de falla de FutureCallback.

¿Guava ya tiene algo como esto? ¿No es recomendable intentar emparejar tiempos de espera con las devoluciones de llamada?

EDITAR: Incluye un ejemplo del código que me llevó a este punto. Obviamente, eliminé las partes significativas para obtener un ejemplo mínimo.

@Test public void testFuture() { Callable<Boolean> callable = new Callable<Boolean>() { @Override public Boolean call() throws Exception { while(true); } }; ListenableFuture<Boolean> callableFuture = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()).submit(callable); Futures.addCallback(callableFuture, new FutureCallback<Boolean>() { @Override public void onFailure(Throwable arg0) { System.out.println("onFailure:"+arg0); } @Override public void onSuccess(Boolean arg0) { System.out.println("onSuccess:"+arg0); } }); try { callableFuture.get(1000, TimeUnit.MILLISECONDS); }catch(Throwable t) { System.out.println("catch:"+t); } }

Este código solo imprimirá catch:java.util.concurrent.TimeoutException .


Actualización: esto se ha agregado a Guava como Futures.withTimeout() .

Internamente, tenemos un método makeTimeoutFuture que toma un Future como entrada y devuelve un nuevo Future que tendrá el mismo resultado a menos que el original no se haya completado en un plazo determinado. Si la fecha límite expira, la salida Future tiene su resultado configurado en TimeoutException . Por lo tanto, puede llamar a makeTimeoutFuture y asociar oyentes al resultado Future .

makeTimeoutFuture no es la solución más natural para su problema. De hecho, creo que el método fue creado principalmente para establecer un tiempo de espera exagerado en las llamadas no-arg get() , ya que puede ser doloroso propagar la fecha límite deseada para todas las personas que llaman. Una solución más natural es razonar que get() es get(long, TimeUnit) como addCallback(ListenableFuture, FutureCallback) es addCallback(ListenableFuture, FutureCallback, long, TimeUnit, SchededuledExecutorService) . Eso es un poco torpe, aunque menos que makeTimeoutFuture . Me gustaría pensar más en esto antes de comprometerme con algo. ¿ Presentaría una solicitud de función ?

(Esto es lo que tenemos internamente :)

public static <V> ListenableFuture<V> makeTimeoutFuture( ListenableFuture<V> delegate, Duration duration, ScheduledExecutorService scheduledExecutor)

Devuelve un futuro que delega a otro pero finalizará temprano (a través de TimeoutException envuelto en una ExecutionException ) si la duración especificada expira. El futuro delegado no se cancela en este caso.

scheduledExecutor.schedule(new Runnable() { @Override public void run() { TimeoutFuture.this.setException(new TimeoutException("Future timed out")); } }, duration.getMillis(), TimeUnit.MILLISECONDS);