Reactor NettyでSpring Webfluxマイクロサービスを使用しているユースケースでは、次の依存関係があります。
org.springframework.boot.spring-boot-starter-webflux
_(2.0.1.RELEASE)org.springframework.boot.spring-boot-starter-data-mongodb-reactive
_(2.0.1.RELEASE)org.projectreactor.reactor-spring
_(1.0.1.RELEASE)非常に特定のケースでは、Mongoデータベースからいくつかの情報を取得し、これをリアクティブWebClient
で送信するクエリパラメーターに処理する必要があります。 WebClient
もUriComponentsBuilder
もパブリッシャー(Mono/Flux)を受け入れるため、#block()
呼び出しを使用して結果を受け取りました。
最新の_reactor-core
_(バージョン2.0.1.RELEASE)に含まれている_spring-boot-dependencies
_(バージョン0.7.6.RELEASE)以降、使用できないblock()/blockFirst()/blockLast() are blocking, which is not supported in thread xxx
、参照-> https://github.com/reactor/reactor-netty/issues/312
私のコードスニペット:
_public Mono<FooBar> getFooBar(Foo foo) {
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
parameters.add("size", foo.getSize());
parameters.addAll("bars", barReactiveCrudRepository.findAllByIdentifierIn(foo.getBarIdentifiers()) // This obviously returns a Flux
.map(Bar::toString)
.collectList()
.block());
String url = UriComponentsBuilder.fromHttpUrl("https://base-url/")
.port(8081)
.path("/foo-bar")
.queryParams(parameters)
.build()
.toString();
return webClient.get()
.uri(url)
.retrieve()
.bodyToMono(FooBar.class);
}
_
これは_spring-boot
_バージョン2.0.0.RELEASEで機能しましたが、バージョン2.0.1.RELEASEへのアップグレード、したがって_reactor-core
_からバージョン0.7.6.RELEASEへのアップグレード以降は許可されません。
私が見る唯一の本当の解決策は、ブロック(非反応)リポジトリ/ mongoクライアントも含めることですが、それが推奨されるかどうかはわかりません。助言がありますか?
WebClient
はリクエストURLにPublisher
タイプを受け入れませんが、次のことを妨げるものはありません。
public Mono<FooBar> getFooBar(Foo foo) {
Mono<List<String>> bars = barReactiveCrudRepository
.findAllByIdentifierIn(foo.getBarIdentifiers())
.map(Bar::toString)
.collectList();
Mono<FooBar> foobar = bars.flatMap(b -> {
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
parameters.add("size", foo.getSize());
parameters.addAll("bars", b);
String url = UriComponentsBuilder.fromHttpUrl("https://base-url/")
.port(8081)
.path("/foo-bar")
.queryParams(parameters)
.build()
.toString();
return webClient.get()
.uri(url)
.retrieve()
.bodyToMono(FooBar.class);
});
return foobar;
}
どちらかといえば、この新しいリアクターコアの検査により、WebFluxハンドラーの途中でこのブロック呼び出しを行うことで、アプリケーション全体がクラッシュすることを防ぎました。