簡體   English   中英

Flux.generate() 正在拋出 java.lang.IllegalStateException:生成器沒有調用任何 SynchronousSink 方法

[英]Flux.generate() is throwing java.lang.IllegalStateException: The generator didn't call any of the SynchronousSink method

我正在嘗試使用 Spring Boot (2.3.4.RELEASE) 進行反應式編程的第一步。 So far I am trying to creating an infinte stream of persons in a service method which is called in a REST controller method but it ends with that exception: "java.lang.IllegalStateException: The generator didn't call any of the SynchronousSink method "我試圖用谷歌搜索一些解決方案幾個小時,但我沒有找到任何適合我想要做的事情的合適的解決方案。

這是我的服務方法:

public Flux<PersonEntity> streamPersons() {
        return personRepository.findMinId()
                .zipWith(personRepository.findMaxId())
                .flatMapMany(minMaxTuple ->
                        Flux.<PersonEntity> generate(stream ->
                                personRepository.findById(new Random().longs(minMaxTuple.getT1(), minMaxTuple.getT2()).findFirst().getAsLong()
                                )
                        ).delayElements(Duration.ofMillis(300))
                );
    } 

更新 1

我從以下答案的最新更新中嘗試了此代碼片段。 方法現在看起來像這樣:

    public Flux<PersonEntity> streamPersons() {
        return personRepository.findMinId()
                .zipWith(personRepository.findMaxId())
                .flatMapMany(minMaxTuple ->
                        Flux.<PersonEntity>generate(sink -> {
                            Mono<PersonEntity> foundStock = stockRepository.findById(new Random().longs(minMaxTuple.getT1(), minMaxTuple.getT2()).findFirst().getAsLong());
                            sink.next(foundStock);
                        }
                        ).delayElements(Duration.ofMillis(300))
                );
    }

不幸的是,我遇到了編譯器錯誤,我不知道如何擺脫它。 局部變量 foundStock 是一個 Mono,但是方法 sink.next(...) 需要一個常規的 PersonEntity。 如何在不阻塞的情況下轉換它?

更新 2

這個解決方案就是對我有用的解決方案。 我的意圖是從數據庫中隨機獲取一個人到 stream 它在一個無限的 stream 到請求實例。 特別感謝@Toerktumlare!

public Flux<PersonEntity> streamPersons() {
    Mono<Tuple2<Long, Long>> minMaxIdTuple = personRepository.findMinId()
            .zipWith(personRepository.findMaxId());
    Flux<Long> interval = Flux.interval(Duration.ofSeconds(1));
    
    return interval.flatMapSequential(aLong ->
           minMaxIdTuple.map(minMaxTuple ->
                new Random().longs(minMaxTuple.getT1(), minMaxTuple.getT2()))
                    .flatMapMany(longStream -> personRepository.findById(
                         longStream.findFirst().getAsLong()))
                    .flatMap(Flux::just)
        );
    }

我的 controller 方法如下所示:

    @GetMapping(value = "/person/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<PersonEntity> streamPersons() {
        return personService.streamPersons();
    }

上述異常的完整堆棧跟蹤

java.lang.IllegalStateException: The generator didn't call any of the SynchronousSink method
    at reactor.core.publisher.FluxGenerate$GenerateSubscription.slowPath(FluxGenerate.java:276) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    |_ checkpoint ⇢ Handler first.reactive.steps.controller.provider.PersonController#streamPersons() [DispatcherHandler]
    |_ checkpoint ⇢ HTTP GET "/personapp/api/v1/persons/stream" [ExceptionHandlingWebHandler]
Stack trace:
        at reactor.core.publisher.FluxGenerate$GenerateSubscription.slowPath(FluxGenerate.java:276) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxGenerate$GenerateSubscription.request(FluxGenerate.java:204) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onSubscribeInner(MonoFlatMapMany.java:143) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onSubscribe(MonoFlatMapMany.java:237) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxGenerate.subscribe(FluxGenerate.java:83) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.Flux.subscribe(Flux.java:8325) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onNext(MonoFlatMapMany.java:188) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1782) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoZip$ZipCoordinator.signal(MonoZip.java:247) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoZip$ZipInner.onNext(MonoZip.java:329) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:76) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.tryEmitScalar(FluxFlatMap.java:480) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:413) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxBuffer$BufferExactSubscriber.onComplete(FluxBuffer.java:179) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2016) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredComplete(FluxUsingWhen.java:402) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxUsingWhen$CommitInner.onComplete(FluxUsingWhen.java:536) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2016) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2016) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.Operators$MonoSubscriber.onComplete(Operators.java:1824) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoIgnoreThen$ThenAcceptInner.onComplete(MonoIgnoreThen.java:314) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.Operators$MonoSubscriber.onComplete(Operators.java:1824) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoIgnoreThen$ThenAcceptInner.onComplete(MonoIgnoreThen.java:314) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.pool.SimpleDequePool$QueuePoolRecyclerInner.onComplete(SimpleDequePool.java:555) ~[reactor-pool-0.1.6.RELEASE.jar:0.1.6.RELEASE]
        at reactor.core.publisher.Operators.complete(Operators.java:135) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:45) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4213) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.pool.SimpleDequePool$QueuePoolRecyclerMono.subscribe(SimpleDequePool.java:667) ~[reactor-pool-0.1.6.RELEASE.jar:0.1.6.RELEASE]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:153) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:153) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4213) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:97) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onError(MonoIgnoreElements.java:76) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:134) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onError(FluxFilterFuseable.java:156) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onError(FluxFilterFuseable.java:375) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onError(FluxMapFuseable.java:326) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onNext(FluxHandleFuseable.java:185) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2344) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.request(FluxHandleFuseable.java:243) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.request(FluxMapFuseable.java:346) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.request(FluxFilterFuseable.java:403) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:184) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:162) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onSubscribe(MonoIgnoreElements.java:64) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onSubscribe(FluxFilterFuseable.java:81) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onSubscribe(FluxFilterFuseable.java:298) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onSubscribe(FluxMapFuseable.java:255) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onSubscribe(FluxHandleFuseable.java:148) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoCurrentContext.subscribe(MonoCurrentContext.java:35) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4213) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onComplete(FluxUsingWhen.java:394) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:838) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:600) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:580) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:457) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onComplete(FluxContextStart.java:115) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at io.r2dbc.postgresql.util.FluxDiscardOnCancel$FluxDiscardOnCancelSubscriber.onComplete(FluxDiscardOnCancel.java:99) ~[r2dbc-postgresql-0.8.5.RELEASE.jar:0.8.5.RELEASE]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onComplete(FluxMapFuseable.java:144) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onComplete(FluxMapFuseable.java:144) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxWindowPredicate$WindowPredicateMain.checkTerminated(FluxWindowPredicate.java:520) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxWindowPredicate$WindowPredicateMain.drainLoop(FluxWindowPredicate.java:468) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxWindowPredicate$WindowPredicateMain.drain(FluxWindowPredicate.java:412) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxWindowPredicate$WindowPredicateMain.onComplete(FluxWindowPredicate.java:293) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxCreate$BaseSink.complete(FluxCreate.java:438) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxCreate$BufferAsyncSink.drain(FluxCreate.java:784) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxCreate$BufferAsyncSink.complete(FluxCreate.java:732) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxCreate$SerializedSink.drainLoop(FluxCreate.java:239) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxCreate$SerializedSink.drain(FluxCreate.java:205) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxCreate$SerializedSink.complete(FluxCreate.java:196) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at io.r2dbc.postgresql.client.ReactorNettyClient$Conversation.complete(ReactorNettyClient.java:709) ~[r2dbc-postgresql-0.8.5.RELEASE.jar:0.8.5.RELEASE]
        at io.r2dbc.postgresql.client.ReactorNettyClient$BackendMessageSubscriber.emit(ReactorNettyClient.java:974) ~[r2dbc-postgresql-0.8.5.RELEASE.jar:0.8.5.RELEASE]
        at io.r2dbc.postgresql.client.ReactorNettyClient$BackendMessageSubscriber.onNext(ReactorNettyClient.java:850) ~[r2dbc-postgresql-0.8.5.RELEASE.jar:0.8.5.RELEASE]
        at io.r2dbc.postgresql.client.ReactorNettyClient$BackendMessageSubscriber.onNext(ReactorNettyClient.java:757) ~[r2dbc-postgresql-0.8.5.RELEASE.jar:0.8.5.RELEASE]
        at reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:112) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onNext(FluxPeekFuseable.java:845) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:213) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:213) ~[reactor-core-3.3.10.RELEASE.jar:3.3.10.RELEASE]
        at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:256) ~[reactor-netty-0.9.12.RELEASE.jar:0.9.12.RELEASE]
        at reactor.netty.channel.FluxReceive.onInboundNext(FluxReceive.java:362) ~[reactor-netty-0.9.12.RELEASE.jar:0.9.12.RELEASE]
        at reactor.netty.channel.ChannelOperations.onInboundNext(ChannelOperations.java:358) ~[reactor-netty-0.9.12.RELEASE.jar:0.9.12.RELEASE]
        at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:96) ~[reactor-netty-0.9.12.RELEASE.jar:0.9.12.RELEASE]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324) ~[netty-codec-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296) ~[netty-codec-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) ~[netty-transport-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.52.Final.jar:4.1.52.Final]
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.52.Final.jar:4.1.52.Final]
        at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

非常感謝任何幫助或提示。 提前致謝

MonoFlux包含稱為sink的東西。 生成器 function 是生成穩定的 stream 項目的最簡單形式。 默認接收器是synchronous的,用於one-by-one發射,因此是synchronousSink

因此,通過調用生成器方法,您可以公開內部接收器,並且您需要通過調用接收器函數nextcompleteerror function 來通過接收器 api 提供項目。

例子:

Flux<String> flux = Flux.generate(
    () -> 0, 
    (state, sink) -> {
      sink.next("3 x " + state + " = " + 3*state); 
      if (state == 10) sink.complete(); 
      return state + 1; 
    });

這里我們使用 function 簽名:

Flux#generate(Callable<S> stateSupplier, BiFunction<S,SynchronousSink<T>,S> generator)

所以我們是:

  • 我們提供的初始 state 值為 0。
  • 我們使用 state 來選擇發射什么(乘法表中的 3 行)。
  • 我們還使用它來選擇何時停止。
  • 我們返回一個新的 state,我們將在下一次調用中使用它(除非序列在這個調用中終止)。

一旦我們訂閱了通量,這就會開始。

上面的代碼將生成以下序列。

3 x 0 = 0
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27
3 x 10 = 30

在您的代碼中,您沒有在生成 function 中調用 sinks next 方法。

您可以在官方Reactor 文檔中閱讀更多關於接收器和生成器 function 的工作原理 - 生產這些文檔應該是您在谷歌搜索其他任何內容之前的第一個來源。

更新:

發布此答案后,發布了此評論:

“為什么這個例子有效,而不是我的代碼”

他所指的例子是:

Flux<Dish> getDishes() {
    return Flux.<Dish> generate(sink -> sink.next(randomDish())) //
                .delayElements(Duration.ofMillis(250));
}

在這里我們可以清楚地看到他正在使用內部接收sink ,並且每次調用sink#next向訂閱客戶端發送一個隨機菜。

在線程啟動器提供的代碼中:

Flux.<PersonEntity> generate(stream ->
       personRepository.findById(new Random()
           .longs(minMaxTuple.getT1(), minMaxTuple.getT2())
           .findFirst()
           .getAsLong()))
       .delayElements(Duration.ofMillis(300))

沒有使用水槽。

生成器方法用於生成項目,這意味着接收器需要具體的 object。 它不能是MonoFlux 如果您需要返回這些,您可以在它們之間進行轉換並將它們直接返回給客戶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM