Как сделать так, чтобы запрос отправлялся весной и навсегда webflux webclient? - PullRequest
0 голосов
/ 04 ноября 2018

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

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 statment также не работает. Может быть, в некоторых main функциях это работает, но не в приложении Spring. Это не работает, потому что Mono просто создан в этом случае, но никто не запускает его. Любые Mono методы, такие как map, flatMap и т. Д., Являются просто «настройкой» функции, но не моно.

1 Ответ

0 голосов
/ 05 ноября 2018

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

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);
...