Синхронизация ответов rest asyn c с коллекцией в Java - PullRequest
0 голосов
/ 27 мая 2020

Не нашел здесь похожего вопроса, поэтому решил обратиться за помощью. В Java 8 у меня есть метод getEmployees со списком идентификаторов сотрудников в качестве входных данных. В этом методе я отправляю asyn c rest-api запросы другой службе, чтобы получить информацию о каждом сотруднике по его идентификатору. И я пытаюсь сохранить ответы как dto для перечисления и вернуть этот список в результате getEmployees . Вот код:

private List<EmployeeDto> getEmployeeDtos(List<String> employeesIds) {

List<EmployeeDto> result = new ArrayList<>();
for (String id : employeesIds) {
    String empUrl = dataUrl.concat(id);

    ListenableFuture<ResponseEntity<String>> futureResponse = asyncRestTemplate.exchange(
                    empUrl,
                    HttpMethod.GET,
                    StringUtils.isEmpty(token) ? createRequest() : createRequest(token),
                    String.class
                );
    futureResponse.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
                    @SneakyThrows
                    @Override
                    public void onFailure(Throwable throwable) {
                        result.add(null);
                    }

                    @SneakyThrows
                    @Override
                    public void onSuccess(ResponseEntity<String> stringResponseEntity) {
                        ResponseEntity<String> response = futureResponse.get();
                        EmployeeDto dto = objectMapper.readValue(response.getBody(), new TypeReference<EmployeeDto>() {
                        });
                        result.add(dto);
                    }
                });

    while (result.size() != employeesIds.size()) {
    }
    return result;
}

Мне не очень нравится while l oop для синхронизации сбора результатов перед возвращением результата. Есть ли идеи, как правильно вернуть всю коллекцию результатов без while l oop в этом случае?

1 Ответ

0 голосов
/ 27 мая 2020

Подсчет вызовов обратного вызова с использованием CountDownLatch:

CountDownLatch latch = new CountDownLatch(employeesIds.size);
....
result.add(null);
latch.countDown();
....
result.add(dto);
latch.countDown();
...
if (!latch.await(20,  TimeUnit.SECONDS)) {
   throw new TimeoutException();
}
return result;

Кроме того, result должен быть синхронизированной коллекцией, иначе методы обратного вызова должны быть синхронизированы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...