• @guqing guqing pushed to refactor/4242 in guqing/halo

    Below is the list of commits:

    0 0
  • @guqing guqing commented on issue #4243 in halo-dev/halo

    /close

    0 0
  • @guqing guqing commented on issue #4243 in halo-dev/halo

    /kind support

    0 0
  • @guqing guqing commented on issue #4243 in halo-dev/halo

    1.x 版本并不支持多用户,只支持单个超管用户,如果需要多用户可以使用 2.x 版本

    0 0
  • @guqing guqing commented on issue #4245 in halo-dev/halo

    /hold 等待 #4241 合并避免重复测试

    0 0
  • @guqing guqing opened pull request #4245 in halo-dev/halo

    What type of PR is this?

    /kind improvement
    /area core
    /area plugin
    /milestone 2.8.x

    What this PR does / why we need it:

    修复由于多线程环境下导致的插件卸载时的路由异常问题

    改动描述:
    为了确保在多线程环境下访问 ExtensionContextRegistry 类的注册表时的线程安全。通过添加读写锁,可以保证在读取和写入PluginApplicationContext 时只有一个线程可以访问,从而避免了多个线程同时访问注册表时可能出现的竞态条件和数据不一致的问题。同时,更新了 register、remove、getByPluginId、containsContext 和 getPluginApplicationContexts 方法,以在访问注册表时获取和释放适当的锁,从而确保了线程安全。

    问题原因:
    当插件卸载时,卸载动作在 Reconciler 线程中执行而路由访问是在 reactor 的 NonBlockingThread 线程执行,当 PluginCompositeRouterFunction 的 routerFunctions() 方法从 ExtensionContextRegistry 中获取所有 PluginApplicationContext 并持有还未处理完成时由于 PluginReconciler 中执行了卸载插件逻辑而将某个 PluginApplicationContext 关闭从而让 PluginCompositeRouterFunction 中持有到的对象引用发生变化出现数据不一致问题导致出现 PluginApplicationContext@14971c8e has been closed already 异常。

    解决方案:
    所以此修改让读取和写入PluginApplicationContext 时只有一个线程可以访问来解决此问题

    how to test it?
    测试开发模式下卸载插件时是否会出现如 #4242 中所描述的异常信息

    Which issue(s) this PR fixes:

    Fixes #4242

    Does this PR introduce a user-facing change?

    修复由于多线程环境下导致的插件卸载时的路由异常问题
    
    0 0
  • @guqing guqing pushed to refactor/4242 in guqing/halo

    Below is the list of commits:

    • refactor: add read-write lock to ExtensionContextRegistry (96521a5)
    0 0
  • @guqing guqing created branch refactor/4242 in guqing/halo

    guqing/halo

    一款优秀的开源博客发布应用。

    0 0
  • @guqing guqing pushed to main in guqing/halo

    Below is the list of commits:

    0 0
  • @guqing guqing opened issue #4242 in halo-dev/halo

    是什么版本出现了此问题?

    2.7.0

    使用的什么数据库?

    H2

    使用的哪种方式部署?

    Docker

    在线站点地址

    No response

    发生了什么?

    开发模式下插件卸载时会抛出 run.halo.app.plugin.PluginApplicationContext@14971c8e has been closed already 异常,生产模式下暂未发现,原因是 PluginCompositeRouterFunction 中

    getInstance().getPluginApplicationContexts()
                .forEach(context -> context.getBeanProvider(CustomEndpoint.class)

    getInstance().getPluginApplicationContexts() 获取到 PluginContext 然后使用时某个 Context 被 close 导致

    相关日志输出

    <details>
    <summary>点击展开异常日志</summary>
    
    java.lang.IllegalStateException: run.halo.app.plugin.PluginApplicationContext@14971c8e has been closed already
    	at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1138) ~[spring-context-6.0.10.jar:6.0.10]
    	Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
    Error has been observed at the following site(s):
    	*__checkpoint ⇢ run.halo.app.console.ConsoleProxyFilter [DefaultWebFilterChain]
    	*__checkpoint ⇢ run.halo.app.security.InitializeRedirectionWebFilter [DefaultWebFilterChain]
    	*__checkpoint ⇢ run.halo.app.security.authentication.login.UsernamePasswordLogoutHandler [DefaultWebFilterChain]
    	*__checkpoint ⇢ run.halo.app.security.authentication.login.DelegatingLogoutPageGeneratingWebFilter [DefaultWebFilterChain]
    	*__checkpoint ⇢ run.halo.app.security.authentication.login.UsernamePasswordAuthenticator [DefaultWebFilterChain]
    	*__checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
    	*__checkpoint ⇢ org.springframework.web.filter.reactive.ServerHttpObservationFilter [DefaultWebFilterChain]
    	*__checkpoint ⇢ HTTP GET "/console/" [ExceptionHandlingWebHandler]
    Original Stack Trace:
    		at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1138) ~[spring-context-6.0.10.jar:6.0.10]
    		at org.springframework.context.support.AbstractApplicationContext.getBeanProvider(AbstractApplicationContext.java:1183) ~[spring-context-6.0.10.jar:6.0.10]
    		at run.halo.app.plugin.PluginCompositeRouterFunction.lambda$routerFunctions$4(PluginCompositeRouterFunction.java:62) ~[classes/:na]
    		at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
    		at run.halo.app.plugin.PluginCompositeRouterFunction.routerFunctions(PluginCompositeRouterFunction.java:62) ~[classes/:na]
    		at run.halo.app.plugin.PluginCompositeRouterFunction.route(PluginCompositeRouterFunction.java:39) ~[classes/:na]
    		at org.springframework.web.reactive.function.server.RouterFunctions$DifferentComposedRouterFunction.route(RouterFunctions.java:1007) ~[spring-webflux-6.0.10.jar:6.0.10]
    		at org.springframework.web.reactive.function.server.RouterFunctions$DifferentComposedRouterFunction.route(RouterFunctions.java:1007) ~[spring-webflux-6.0.10.jar:6.0.10]
    		at org.springframework.web.reactive.function.server.RouterFunctions$DifferentComposedRouterFunction.route(RouterFunctions.java:1007) ~[spring-webflux-6.0.10.jar:6.0.10]
    		at org.springframework.web.reactive.function.server.RouterFunctions$DifferentComposedRouterFunction.route(RouterFunctions.java:1007) ~[spring-webflux-6.0.10.jar:6.0.10]
    		at org.springframework.web.reactive.function.server.RouterFunctions$DifferentComposedRouterFunction.route(RouterFunctions.java:1007) ~[spring-webflux-6.0.10.jar:6.0.10]
    		at org.springframework.web.reactive.function.server.RouterFunctions$DifferentComposedRouterFunction.route(RouterFunctions.java:1007) ~[spring-webflux-6.0.10.jar:6.0.10]
    		at org.springframework.web.reactive.function.server.RouterFunctions$DifferentComposedRouterFunction.route(RouterFunctions.java:1007) ~[spring-webflux-6.0.10.jar:6.0.10]
    		at org.springframework.web.reactive.function.server.RouterFunctions$DifferentComposedRouterFunction.route(RouterFunctions.java:1007) ~[spring-webflux-6.0.10.jar:6.0.10]
    		at org.springframework.web.reactive.function.server.RouterFunctions$DifferentComposedRouterFunction.route(RouterFunctions.java:1007) ~[spring-webflux-6.0.10.jar:6.0.10]
    		at org.springframework.web.reactive.function.server.support.RouterFunctionMapping.getHandlerInternal(RouterFunctionMapping.java:156) ~[spring-webflux-6.0.10.jar:6.0.10]
    		at org.springframework.web.reactive.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:187) ~[spring-webflux-6.0.10.jar:6.0.10]
    		at org.springframework.web.reactive.DispatcherHandler.lambda$handle$0(DispatcherHandler.java:150) ~[spring-webflux-6.0.10.jar:6.0.10]
    		at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.onNext(FluxConcatMapNoPrefetch.java:183) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:335) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:294) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.request(FluxConcatMapNoPrefetch.java:336) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoNext$NextSubscriber.request(MonoNext.java:108) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoNext$NextSubscriber.onSubscribe(MonoNext.java:70) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.onSubscribe(FluxConcatMapNoPrefetch.java:164) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableConditionalSubscriber.onComplete(FluxPeekFuseable.java:595) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:159) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoAll$AllSubscriber.onNext(MonoAll.java:94) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.tryEmit(FluxFlatMap.java:544) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapInner.onNext(FluxFlatMap.java:985) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:210) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapInner.onSubscribe(FluxFlatMap.java:965) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:192) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4480) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:427) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:210) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:335) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:294) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:371) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:210) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoFlatMap$FlatMapMain.request(MonoFlatMap.java:194) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onSubscribe(MonoIgnoreThen.java:134) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:117) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onComplete(FluxPeekFuseable.java:940) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:85) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2547) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:102) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:847) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:609) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:589) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:466) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onComplete(FluxPeekFuseable.java:277) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:357) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:294) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:371) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onComplete(FluxPeekFuseable.java:940) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:85) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2547) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:102) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:847) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:609) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:589) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:466) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onComplete(FluxPeekFuseable.java:277) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:357) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:294) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:371) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoFlatMap$FlatMapMain.onComplete(MonoFlatMap.java:189) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onComplete(FluxPeekFuseable.java:940) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:85) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2547) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:102) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:847) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:609) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:589) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:466) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onComplete(FluxPeekFuseable.java:277) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:357) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:294) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:371) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:102) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFilterWhen$FluxFilterWhenSubscriber.drain(FluxFilterWhen.java:236) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFilterWhen$FluxFilterWhenSubscriber.onComplete(FluxFilterWhen.java:153) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:357) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:294) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxFilterWhen$FluxFilterWhenSubscriber.onSubscribe(FluxFilterWhen.java:200) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55) ~[reactor-core-3.5.7.jar:3.5.7]
    		at reactor.netty.http.server.HttpServer$HttpServerHandle.onStateChange(HttpServer.java:1006) ~[reactor-netty-http-1.1.8.jar:1.1.8]
    		at reactor.netty.ReactorNetty$CompositeConnectionObserver.onStateChange(ReactorNetty.java:710) ~[reactor-netty-core-1.1.8.jar:1.1.8]
    		at reactor.netty.transport.ServerTransport$ChildObserver.onStateChange(ServerTransport.java:481) ~[reactor-netty-core-1.1.8.jar:1.1.8]
    </details>

    附加信息

    /kind bug
    /area core
    /milestone 2.8.x
    /assign

    0 0