Как заставить отправить запрос на запуск и забыть в весеннем веб-клиенте webflux?

Рассмотрим код:

private WebClient webClient;

public void some(MyObject myObject) {
    return webClient.post()
            .uri("/log/my-path")
            .body(BodyInserters.fromObject(myObject))
            .retrieve()
            .bodyToMono(Void.class)
            .subscribeOn(Schedulers.single());
}

Этот код «ждет», когда «появится» ответ, а затем завершается. (Например, retrieve() называется). а как не дождаться ответа? Например, я делаю запрос и возвращаю Mono.empty, не дожидаясь ответа. Как это сделать?

P.S. Прием, когда запрос отправляется без ожидания ответа, называется «выстрелил и забыл».

ОБНОВЛЕНО

  1. Никакие монофункции, такие как then, не работают. Потому что они вызвали после bodyToMono, который «ждет», пока не поступит HTTP-ответ. Например. ничего (асинхронное событие) не вызывается до завершения bodyToMono.
  2. Статус "удалить" return тоже не работает. Может быть, в некоторых main функциях он работает, но не в приложении Spring. Это не работает, потому что Mono только что создан в этом случае, но никто не запускает его. Любые Mono методы, такие как map, flatMap и т. Д., Являются просто "настройкой" функции, но не запуском Mono.

person Cherry    schedule 04.11.2018    source источник
comment
удалите оператор return, и он будет срабатывать в фоновом режиме. Но если вы хотите вернуть Mono.empty, используйте .then (), который является Mono ‹Void›   -  person Kevin Hussey    schedule 05.11.2018
comment
remove the 'return' statement and and it will be fire in the background. Нет, в этом случае моно не запускается.   -  person Cherry    schedule 15.11.2018
comment
Братан, ты решил это?   -  person Mr.Ustiik    schedule 16.04.2021


Ответы (1)


Есть несколько способов сделать это. Вы могли сделать следующее:

public void some(MyObject myObject) {
    return webClient.post()
            .uri("/log/my-path")
            .body(BodyInserters.fromObject(myObject))
            .retrieve()
            .bodyToMono(Void.class)
            .subscribe();
}

Здесь возникает важная проблема: даже если вас не интересует сам ответ, вы можете захотеть иметь определенные свойства, например:

  • Уведомление об ошибках и их устранение.
  • Убедиться, что в случае пакетного / CLI-приложения что-то удерживает этот запрос и предотвращает выход вашего приложения, думая, что все сделано

В этом случае вы можете связать ответ с типом Mono<Void>, который завершается как Mono.empty() или ошибка:

public Mono<Void> some(MyObject myObject) {
    return webClient.post()
            .uri("/log/my-path")
            .body(BodyInserters.fromObject(myObject))
            .retrieve()
            .bodyToMono(Void.class)
            .then();
}

В других частях вашего приложения вы можете снова установить связь с другими издателями:

Mono<Void> requestSent = some(myObject);
Mono<Other> other = requestSent.then(otherMono);
person Brian Clozel    schedule 05.11.2018
comment
then не работает. Проблема здесь в исполнении bodyToMono блоков. Например. он ожидает получения данных и только после этого моно может быть завершено. Есть ли способ пропустить блокировку? - person Cherry; 15.11.2018
comment
Это предполагает чтение небольшого количества данных и отмена + закрытие соединения. Обратной стороной является то, что соединение не возвращается в пул соединений. Мы исправили несколько проблем в этой области (см. jira.spring.io/browse/SPR-17482, jira.spring.io/browse/SPR-17054). Итак, на этом этапе вам лучше всего создать образец приложения с последней версией Spring, которое показывает проблему, и создать новую проблему на jira.spring.io. - person Brian Clozel; 15.11.2018