2017-02-16 26 views
5

Я использую Spring 4.2.3 AsyncRestTemplate.exchange() для вызова некоторого API, который займет несколько секунд, и я ожидаю, что listenableFuture.get (1, TimeUnit.SECONDS) будет блокировать 1 секунду, а затем выбросить TimeOutException.Блокировка на ListenableFuture с тайм-аутом

Что происходит вместо этого является то, что listenableFuture.get() будет блокировать в течение всего времени вызова API (более 1 секунды)

AsyncRestTemplate restTemplate = new AsyncRestTemplate(); 

    ListenableFuture<ResponseEntity<String>> listenableFuture = restTemplate.exchange(URL, HttpMethod.GET, null, String.class); 
    log.debug("before callback"); 

    //...add callbacks 

    try{ 
     log.debug("before blocking"); 
     listenableFuture.get(1, TimeUnit.SECONDS); 
    }catch (InterruptedException e) { 
     log.error(":GOT InterruptedException"); 
    } catch (ExecutionException e) { 
     log.error(":GOT ExecutionException"); 
    } catch (TimeoutException e) { 
     log.info(":GOT TimeoutException"); 
    } 

    log.info("FINISHED"); 

Выход:

09:15:21.596 DEBUG [main] org.springframework.web.client.AsyncRestTemplate:78 - Created asynchronous GET request for "http://localhost:4567/oia/wait?seconds=5" 
    09:15:21.666 DEBUG [main] org.springframework.web.client.RestTemplate:720 - Setting request Accept header to [text/plain, application/xml, text/xml, application/json, application/*+xml, application/*+json, */*] 
    09:15:21.679 DEBUG [main] com.zazma.flow.utils.FutureTest:74 - before callback 
    09:15:21.679 DEBUG [main] com.zazma.flow.utils.FutureTest:95 - before blocking 
    09:15:26.709 DEBUG [main] org.springframework.web.client.AsyncRestTemplate:576 - Async GET request for "http://localhost:4567/oia/wait?seconds=5" resulted in 200 (OK) 
    09:15:26.711 DEBUG [main] org.springframework.web.client.RestTemplate:101 - Reading [java.lang.String] as "text/html;charset=utf-8" using [[email protected]44431a] 
    09:15:26.717 INFO [main] com.zazma.flow.utils.FutureTest:105 - FINISHED 

Вот пример что ListenableFuture.get() будет работать, как ожидается, когда не создается AsyncRestTemplate

SimpleAsyncTaskExecutor te = new SimpleAsyncTaskExecutor(); 
    ListenableFuture<String> lf = te.submitListenable(() -> { 
     Thread.sleep(8000); 
     return "OK"; 
    }); 

    lf.get(1, TimeUnit.SECONDS); 
+0

Почему он говорит «wait? Seconds = 5» в URL-адрес строки 5 в журнале? –

+0

@vstromcoder i создал локальный API, который получает X в качестве номера и ждет X секунд, а затем возвращает OK. Таким образом, URL-адрес, который я передаю в обмен, это API. вот почему я пытаюсь подождать всего 1 секунду, прежде чем API закончит (через 5 секунд) – Yoni

ответ

1

Yo u код совершенно правильный. То, что вызывает проблему, - это ошибка в весеннем контексте. Хотя мне не удалось найти его в пробнике проблем весны (или, возможно, он не документирован), вы можете исправить его, обновив зависимости. Конечно, ваш код будет работать с версией spring-web> = 4.3.2.RELEASE.