Есть ли способ обработки ответов асинхронных процессов по мере их завершения в микросервисах Spring Boot? - PullRequest
0 голосов
/ 18 июня 2019

Предположим, у нас есть 5 различных вызовов службы в одной функции, и все они асинхронные, я хочу обрабатывать каждый из них по мере их завершения.

В качестве примера это 3 разные функции, доступные в 3 разных классах

@Async
public CompletableFuture<Actor> lookForId(String id) throws InterruptedException {
    LOG.info("Looking up Movie ID: {}", Id);
    String url = "http://localhost:7073/data/" + id;
    Actor results = restTemplate.getForObject(url, Actors.class);
    // Artificial delay of 1s for demonstration purposes
    Thread.sleep(1000L);
    return CompletableFuture.completedFuture(results);
}

@Async
public CompletableFuture<Singer> lookForId(String id) throws InterruptedException {
    LOG.info("Looking up Movie ID: {}", id);
    String url = "http://localhost:7075/data/" + id;
    Singer results = restTemplate.getForObject(url, Singer.class);
    // Artificial delay of 1s for demonstration purposes
    Thread.sleep(1000L);
    return CompletableFuture.completedFuture(results);
}

@Async
public CompletableFuture<Writer> lookForId(String id) throws InterruptedException {
    LOG.info("Looking up Movie ID: {}", id);
    String url = "http://localhost:7078/data/" + id;
    Writer results = restTemplate.getForObject(url, Writer.class);
    // Artificial delay of 1s for demonstration purposes
    Thread.sleep(1000L);
    return CompletableFuture.completedFuture(results);
}

И вызывающая их функция выглядит следующим образом:

public String getResp() throws InterruptedException, ExecutionException {
    long start = System.currentTimeMillis();
    CompletableFuture<Actor> page1 = actorAsyncService.lookForId("0");
    CompletableFuture<Singer> page2 = singerAsyncService.lookForId("2");
    CompletableFuture<Writer> page3 = singerAsyncService.lookForId("4");
    String respStr = page1.get() + "||" + page2.get() + "||" + page3.get() ;
    System.out.println(">>>>>>>>>>>> Elapsed time: " + (System.currentTimeMillis() - start));
    System.out.println("respStr : " + respStr);
    return respStr;
}

Здесь процесс ожидаеткаждый процесс завершается, а затем отправляется обратно ответ, но я хочу, чтобы, как только любой процесс завершился , служба должна возвращать ответ на вызывающую функцию, но также должна иметь возможность обрабатывать ответобеспечивается другими вызовами службы, когда остальная часть процесса завершается или завершается или выдает ответ об ошибке.

Например, если процесс страницы 2 завершается, то ответ этого процесса возвращается к вызывающей функции, но функция все же должна иметь возможность обрабатывать ответсо страницы 1 и страницы 2 после завершения процесса.

1 Ответ

0 голосов
/ 18 июня 2019

CompletableFuture.anyOf() возвращает новое CompletableFuture, которое завершается при завершении любого из заданного CompletableFutures с тем же результатом.

Вот мой пример:

public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("task 1 finished");
            return "task 1";
        });

        CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("task 2 finished");
            return "task 2";
        });

        CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("task 3 finished");
            return "task 3";
        });
        CompletableFuture<Object> future = CompletableFuture.anyOf(task1, task2, task3);
        String result = (String)future.get();
        System.out.println(result);

        task1.join();
        task2.join();
        task3.join();
    }

И вывод:

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