Есть ли способ объединить в Java Spring непредсказуемое количество Monos в списке? - PullRequest
1 голос
/ 24 января 2020

У меня есть метод Mono >, который принимает один параметр из списка URN.

public Mono <List <MyObject>> loadMyObjectsFromUrnAsync (Iterable <String> urns) {...}

В зависимости от количества URN, у меня есть сделать несколько асинхронных HTTP-запросов, каждый из которых представлен Mono. Поскольку я хочу, чтобы программа могла перемещаться в другие части программы во время выполнения этого метода и выполнения всех запросов, как мне go о сжатии различных Monos и возврате результата для единственного Mono?

... {
   List <Mono <MyObject>> myList = new Arraylist <Mono <MyObject>> ();
   while (urns.hasNext()) {
      // create a Mono HTTP request with the current iterated URN 
      myList.add(request); }
   return mono.zip(myList);
   }...

Код, приведенный выше, очевидно, не работает, он просто поможет облегчить понимание моего вопроса. Я не смог найти в сети документацию о том, как сжать список Monos без указания каждого Mono

1 Ответ

0 голосов
/ 13 февраля 2020

Возможно, описанная выше проблема не была четко передана, поэтому я просто перефразирую ее и затем опишу свое решение. Надеюсь, это поможет кому-то!

Также важное примечание: это решение сделано в Java Spring с использованием WebClient для выполнения асинхронных запросов на стороне клиента к удаленному серверу.

В зависимости от количества URN, Я должен сделать несколько асинхронных HTTP-запросов, каждый из которых представлен Mono.

Допустим, есть функция, которая принимает ArrayList конечных точек HTTP и возвращает ArrayList типа MyObject. Я хочу, чтобы эта функция принимала эти конечные точки и выполняла соответствующее количество HTTP-запросов с использованием Monos, которые будут заполнять это количество объектов POJO MyObject (простых старых Java объектов), однако, поскольку число Monos будет отличаться в зависимости от количества конечных точек Я не могу явно определить каждый моно. Я использую Monos, чтобы позволить мне выполнять эти запросы параллельно или одновременно, а не последовательно по одному, и я хочу получать уведомления, когда все мои Monos завершены и могут создавать экземпляры MyObject.

Поскольку я хочу, чтобы программа могла перемещаться на другие части программы при выполнении этого метода и выполнении всех запросов, как мне go сообщить о сжатии различных Monos и возврате результата для единственного объединенного потока, когда он завершится?

Решением для организации набора непредсказуемых моносов является сохранение итерируемого монослоя и слияние его в поток, который затем буферизуется и блокируется для создайте Java объекты!

(Важно понять, что такое Monos и Flux, чтобы полностью понять это решение)

public Mono<MyObject> getOneObject(String endpoint) {
    return webClient.get()
        .uri(endpoint)
        .retrieve()
        .bodyToMono(MyObject.class)
}

Эта функция выше извлекает один объект на основе одного конечная точка. Теперь давайте создадим Iterable из Monos на основе заданного списка конечных точек.

public Iterable<Mono<MyObject>> getMultipleObjects(ArrayList<String> endpoints) {
    ArrayList<Mono<MyObject>> monos = new ArrayList<Mono<MyObject>> ();
    for (String endpoint: endpoints) {
         monos.add(getOneObject(endpoint));
    }
    return monos;
}

Эта функция возвращает ArrayList (приведенный к Iterable в операторе return), который заполняется путем перебора списка конечных точек. Теперь давайте объединяем повторяющиеся моно в единый поток!

public Flux<MyObject> mergeMultipleMonos(Iterable<Mono<MyObject>> multipleMonos) {
    return Flux.merge(multipleMonos);
}

Теперь все, что вам нужно сделать, это создать буфер и заблокировать поток для создания ArrayList объектов!

public ArrayList<MyObject> listOfObjects(Flux<MyObject> fluxOfObjects) {
    return fluxOfObjects.buffer().blockLast();
}

Flux.buffer () соберет все входящие значения в list, и Flux.blockLast () подпишется на этот поток и будет блокироваться на неопределенный срок, пока восходящий поток не сообщит свое последнее значение или не завершится.

И вот как непредсказуемое число Monos, в данном случае представляющее асинхронные клиентские веб-запросы HTTP, может быть объединено в единый поток, который также будет заполнять все значения, когда каждый запрос будет возвращен!

...