Каков будет результат приведенного ниже кода java в случае частичного сбоя во время вызовов API?

#java-8 #java-stream #rest

Вопрос:

У меня есть список из 115 входов, который разделен на пакеты размером по 20 входов каждый, используя приведенный ниже код, что означает xoneIndexListOfList , что он содержит 6 элементов с размером [ [20], [20], [20], [20], [20], [15] ] соответственно.

 final AtomicInteger counter = new AtomicInteger();
final Collection<List<XoneIndexRequest>> xoneIndexListOfList = xoneIndexRequestList.stream()
          .collect(Collectors.groupingBy(it -> counter.getAndIncrement() / xoneIndicesPacketSize))
              .values(); 
 

На втором шаге я повторяю этот список и передаю каждый пакет в качестве входных данных в некоторую конечную точку REST, используя приведенный ниже код.

 return xoneIndexListOfList.stream()
       .map(e -> {
            return getResponseBody(creditIndicesApiClient.creditIndicesSearch7(e));
       }).collect(Collectors.toList());
 

Из приведенного выше кода мы могли видеть, что 6 вызовов будут отправлены в указанный выше API(т. е. по одному для каждого пакета), поэтому здесь мой вопрос, что произойдет в случае частичного сбоя?

Сценарий : Предположим, что пакеты 1 и 2 прошли, а пакет 3 не удался ( т. Е. API не может возвращать данные для 3-х пакетов)

**Вопрос : **

  1. В приведенном выше сценарии будет ли он переходить к 4 и 5 пакетам? Если да, то предположим, что пакеты 4 и 5 также прошли, так что в общей сложности пакет 1,2,4,5 прошел, но 3 не удалось, так каков будет обратный вывод из приведенного выше кода?
  2. Если нет, то им будет просто возвращен вывод для пакетов 1 и 2, потому что он уже был передан, а запрос не удался для пакета 3?
  3. или он будет помечать каждый пакет как неудачный, если какой-либо из них в любой момент завершится неудачей при обработке этого списка пакетов?

РЕДАКТИРОВАТЬ — Добавление полного метода

 @Override
public List<XoneIndexResponse> creditIndicesSearch7(List<XoneIndexRequest> xoneIndexRequestList) {

    try {

        final AtomicInteger counter = new AtomicInteger();
        final Collection<List<XoneIndexRequest>> xoneIndexListOfList = xoneIndexRequestList.stream()
            .collect(Collectors.groupingBy(it -> counter.getAndIncrement() / xoneIndicesPacketSize))
            .values();

        return xoneIndexListOfList.stream()
            .map(e -> {
               return getResponseBody(creditIndicesApiClient.creditIndicesSearch7(e));
            }).collect(Collectors.toList());

    } catch (Exception e) {
        log.error("error while retrieving data from x-one! for Index", e);
        return emptyList();
    }
}
 

Ответ №1:

При возникновении необработанного исключения обработка потока немедленно прекращается.

Таким образом, вы не получите список, если не обработаете исключение.

Мы можем протестировать его с помощью следующего кода:

 Stream.of(6, 0, 7)
        .map(integer -> 5/integer   integer)
        .forEach(System.out::println);
 

Выход:

 6
Exception in thread "main" java.lang.ArithmeticException: / by zero
    at com.example.demo.DemoApplication.lambda$main$8(DemoApplication.java:244)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
    at com.example.demo.DemoApplication.main(DemoApplication.java:245)
 

Это зависит от того, что мы пытаемся сделать, но мы можем исправить это с помощью:

 Stream.of(6, 0, 7)
        .map(integer -> {
            try{
                return  Optional.of(5/integer   integer);
            }catch (ArithmeticException e){
                return Optional.empty();
            }
        })
        .filter(Optional::isPresent)
        .map(Optional::get)
        .forEach(System.out::println);
 

Выход:

 6
7
 

Редактировать:

Когда все это завернуто в try область видимости, исключение, которое было выброшено из потока, будет распространяться и будет поймано в области catch видимости.

Таким образом, в вашем случае ошибка будет выведена в журнал и emptyList() будет вызвана.

Комментарии:

1. выше весь код написан в блоке try-catch, теперь каково будет поведение?

2. @MOnkey Я отредактировал, чтобы ответить на ваш вопрос 🙂