Тело Spring Webflux выполняется дважды

#spring #spring-boot #reactive-programming #spring-webflux

#весна #пружинный загрузчик #реактивное программирование #spring-webflux

Вопрос:

Я пытаюсь использовать приведенный ниже код в Spring WebFlux, но он выполняется 2 раза. Я использую Spring Boot 2.3.3.RELEASE и MongoDB в качестве базы данных.

Есть 3 репозитория, которые называются: sessionRepo, UserRepo, requestRepo

 public Mono<CustomeResponse> createUpdateUser(Request request) {
  return sessionRepo
    .findBySid(request.getId())
    .log()
    .flatMap(sessionInfo -> userRepo.findById(sessionInfo.getUid())
            .log()
            .map(quoteDocument -> {
    // other update user logic
                userRepo.save(user).subscribe();
    return success;
            })
            .onErrorReturn().defaultIfEmpty())
    .switchIfEmpty(createNewUser(request))
    .onErrorReturn());
    }


public Mono<Success> createNewUser(Request request){
   return requestRepo.findById(request.getRequestInfo().getId())
     .log()
     .map(requestInfo -> {
        // other create user logic
        userRepo.save(user).subscribe();
        return success;
      })
      .defaultIfEmpty()
      .onErrorReturn();
} 
 

Я заметил, что большая часть моего кода выполняется 2 раза. Но во всех API, где я должен создавать новые идентификаторы, такие как session-id, и отправлять их на интерфейс, он всегда отправляет второй, создавая дубликат в базе данных.

Даже switchIfEmpty выполняется 2 раза.

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

1. flatMap элементы цикла один за другим в вашем случае sessionRepo.findBySid(request.getId()) содержат несколько элементов, поэтому ваш switchIfEmpty выполняется дважды, можете ли вы подтвердить со своей стороны?

2. userRepo.save(user).subscribe() также нехорошо, что вы не должны подписываться. Абонент является потребителем, поэтому в вашем случае это вызывающий клиент (веб-страница, мобильное приложение), поскольку именно они инициировали вызов, и это конечный пункт назначения ответа, вместо этого вы должны return userRepo.save(user).thenReturn(success)

3. Привет @Toerktumlare, вы правы, одна из проблем — .subscribe() . Я добавил пример кода в свой репозиторий git: github.com/prathambongale/reactive-practice . В файле README есть информация о том, какую проблему я пытаюсь решить.