2012-09-12 19 views
32

Guava'nın örneklerine dayanarak, sorunuma zarif çözümler aradığımı gördüm. Özellikle, Futures.addCallback(ListenableFuture, FutureCallback) çalışma şeklini seviyorum, ancak FutureCallback çağrılmadan önce zaman aşımına uğrayabilecek bir zaman aşımı ayarlayabilmek istiyorum. Optimal Zaman aşımını ihlal etmesi, sadece FutureCallback'in çağrılması gereken bir arıza durumuna yol açması hoş olurdu.ListenableFuture, FutureCallback ve zaman aşımları

Guava'nın halihazırda böyle bir şey var mı? Geri aramalarla zaman aşımlarını eşleştirmeyi denemeniz tavsiye edilmiyor mu?

DÜZENLEME: Beni bu noktaya yönlendiren kodun örneği dahil. Açıkçası, asgari bir örnek almak için anlamlı bitleri çıkardım.

@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); 
    } 
} 

Bu kod yalnızca catch:java.util.concurrent.TimeoutException'u basacaktır.

cevap

21

Güncelleme: Bu Guava sitesine Futures.withTimeout() olarak eklendi.


Dahili olarak, biz girdi olarak bir Future alır ve orijinal belirli bir tarihe kadar tamamlamamış sürece aynı sonucu sahip olacak yeni Future döndüren bir makeTimeoutFuture yöntemi var. Son tarihin sona ermesi durumunda, Future çıkışının sonucu TimeoutException olarak ayarlanmıştır. Böylece makeTimeoutFuture'u arayabilir ve Future çıkışına dinleyicileri ekleyebilirsiniz. Sorununuz için en doğal çözüm bulamayız

Aslında, yöntemin öncelikle argümanı get() no'lu aramalarda zor zaman aşımına uğratmak için yaratıldığını düşünüyorum, çünkü aranan süreyi tüm arayanlara yaymak bir acı olabilir. Daha doğal bir çözüm, get()'un addCallback(ListenableFuture, FutureCallback)'un addCallback(ListenableFuture, FutureCallback, long, TimeUnit, SchededuledExecutorService)'a göre get(long, TimeUnit) olması nedenidir. Bu biraz sakar, makeTimeoutFuture'dan daha az olsa da. Bir şey yapmaya başlamadan önce bunu daha çok düşünmek istiyorum. file a feature request yapar mısın?

(Burada dahili olarak sahip olduğun :) Belirtilen süre süresi dolarsa

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

) bir ExecutionException sarılmış bir TimeoutException üzerinden başka delegeler ama erken sona ereceğini bir gelecek (döndürür. Bu durumda delege geleceği iptal edilmez.

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

Inisght için teşekkürler. İsteği şu anda açtım (http://code.google.com/p/guava-libraries/issues/detail?id=1146&thanks=1146&ts=1347504235). –

İlgili konular