Azure / azure-sdk-for-java

This repository is for active development of the Azure SDK for Java. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/java/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-java.
MIT License
2.31k stars 1.96k forks source link

[BUG] "java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking" when attempting to refresh Application Configuration settings #35845

Open aleksanderKopec opened 1 year ago

aleksanderKopec commented 1 year ago

Describe the bug When attempting to refresh the configuration values using AppConfigurationRefresh, we are getting an exception because of an .block() in the configuration refresh code.

Exception or Stack Trace

        at reactor.core.publisher.Mono.block(Mono.java:1710) ~[reactor-core-3.5.6.jar:3.5.6]
        at com.azure.core.http.policy.HttpPipelinePolicy.processSync(HttpPipelinePolicy.java:39) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:41) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.HttpPipelineSyncPolicy.processSync(HttpPipelineSyncPolicy.java:42) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:41) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.data.appconfiguration.implementation.ConfigurationCredentialsPolicy.processSync(ConfigurationCredentialsPolicy.java:69) ~[azure-data-appconfiguration-1.4.4.jar:1.4.4]
        at com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:41) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.HttpPipelineSyncPolicy.processSync(HttpPipelineSyncPolicy.java:42) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.AddDatePolicy.processSync(AddDatePolicy.java:53) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:41) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.RetryPolicy.attemptSync(RetryPolicy.java:176) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.RetryPolicy.attemptSync(RetryPolicy.java:188) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.RetryPolicy.attemptSync(RetryPolicy.java:188) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.RetryPolicy.processSync(RetryPolicy.java:126) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:41) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.HttpPipelineSyncPolicy.processSync(HttpPipelineSyncPolicy.java:42) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.AddHeadersPolicy.processSync(AddHeadersPolicy.java:45) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:41) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.HttpPipelineSyncPolicy.processSync(HttpPipelineSyncPolicy.java:42) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.AddHeadersFromContextPolicy.processSync(AddHeadersFromContextPolicy.java:76) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:41) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.HttpPipelineSyncPolicy.processSync(HttpPipelineSyncPolicy.java:42) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.RequestIdPolicy.processSync(RequestIdPolicy.java:69) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:41) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.HttpPipelineSyncPolicy.processSync(HttpPipelineSyncPolicy.java:42) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.policy.UserAgentPolicy.processSync(UserAgentPolicy.java:153) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:41) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.HttpPipeline.sendSync(HttpPipeline.java:131) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.implementation.http.rest.SyncRestProxy.send(SyncRestProxy.java:54) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.implementation.http.rest.SyncRestProxy.invoke(SyncRestProxy.java:75) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.implementation.http.rest.RestProxyBase.invoke(RestProxyBase.java:109) ~[azure-core-1.38.0.jar:1.38.0]
        at com.azure.core.http.rest.RestProxy.invoke(RestProxy.java:91) ~[azure-core-1.38.0.jar:1.38.0]
        at jdk.proxy2.$Proxy56.getKeyValue(Unknown Source) ~[?:?]
        at com.azure.data.appconfiguration.implementation.ConfigurationClientImpl.getConfigurationSettingWithResponse(ConfigurationClientImpl.java:492) ~[azure-data-appconfiguration-1.4.4.jar:1.4.4]
        at com.azure.data.appconfiguration.ConfigurationClient.getConfigurationSetting(ConfigurationClient.java:367) ~[azure-data-appconfiguration-1.4.4.jar:1.4.4]
        at com.azure.data.appconfiguration.ConfigurationClient.getConfigurationSetting(ConfigurationClient.java:336) ~[azure-data-appconfiguration-1.4.4.jar:1.4.4]
        at com.azure.spring.cloud.appconfiguration.config.implementation.AppConfigurationReplicaClient.getWatchKey(AppConfigurationReplicaClient.java:88) ~[spring-cloud-azure-appconfiguration-config-5.3.0.jar:5.3.0]
        at com.azure.spring.cloud.appconfiguration.config.implementation.AppConfigurationRefreshUtil.refreshWithoutTime(AppConfigurationRefreshUtil.java:192) ~[spring-cloud-azure-appconfiguration-config-5.3.0.jar:5.3.0]
        at com.azure.spring.cloud.appconfiguration.config.implementation.AppConfigurationRefreshUtil.refreshWithTime(AppConfigurationRefreshUtil.java:172) ~[spring-cloud-azure-appconfiguration-config-5.3.0.jar:5.3.0]
        at com.azure.spring.cloud.appconfiguration.config.implementation.AppConfigurationRefreshUtil.refreshStoresCheck(AppConfigurationRefreshUtil.java:65) ~[spring-cloud-azure-appconfiguration-config-5.3.0.jar:5.3.0]
        at com.azure.spring.cloud.appconfiguration.config.implementation.AppConfigurationPullRefresh.refreshStores(AppConfigurationPullRefresh.java:103) ~[spring-cloud-azure-appconfiguration-config-5.3.0.jar:5.3.0]
        at com.azure.spring.cloud.appconfiguration.config.implementation.AppConfigurationPullRefresh.refreshConfigurations(AppConfigurationPullRefresh.java:74) ~[spring-cloud-azure-appconfiguration-config-5.3.0.jar:5.3.0]
        at eu.nets.easy.techopt.flagservice.FlagServiceController.refreshConfig(FlagServiceController.java:93) ~[classes/:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
        at org.springframework.web.reactive.result.method.InvocableHandlerMethod.lambda$invoke$0(InvocableHandlerMethod.java:145) ~[spring-webflux-6.0.9.jar:6.0.9]
        at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:152) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:240) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onComplete(MonoFlatMap.java:189) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators.complete(Operators.java:137) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoZip.subscribe(MonoZip.java:121) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4485) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.innerNext(FluxConcatMapNoPrefetch.java:258) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:863) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:180) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.request(MonoPeekTerminal.java:139) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.request(Operators.java:2305) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.request(FluxConcatMapNoPrefetch.java:338) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoNext$NextSubscriber.request(MonoNext.java:108) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoNext$NextSubscriber.onSubscribe(MonoNext.java:70) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.onSubscribe(FluxConcatMapNoPrefetch.java:164) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4485) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onComplete(MonoPeekTerminal.java:299) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onComplete(MonoPeekTerminal.java:299) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:155) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFilter$FilterSubscriber.onNext(FluxFilter.java:113) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:180) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxPeekFuseable$PeekFuseableConditionalSubscriber.onNext(FluxPeekFuseable.java:503) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:180) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onNext(FluxDefaultIfEmpty.java:122) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.innerNext(FluxConcatMapNoPrefetch.java:258) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:863) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:158) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:118) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:191) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.request(MonoFlatMap.java:194) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.request(Operators.java:2305) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.request(FluxConcatMapNoPrefetch.java:338) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoNext$NextSubscriber.request(MonoNext.java:108) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.request(FluxDefaultIfEmpty.java:98) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.request(MonoPeekTerminal.java:139) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxPeekFuseable$PeekFuseableConditionalSubscriber.request(FluxPeekFuseable.java:437) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.request(MonoPeekTerminal.java:139) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFilter$FilterSubscriber.request(FluxFilter.java:186) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFilter$FilterSubscriber.onSubscribe(FluxFilter.java:85) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onSubscribe(MonoPeekTerminal.java:152) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxPeekFuseable$PeekFuseableConditionalSubscriber.onSubscribe(FluxPeekFuseable.java:471) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onSubscribe(MonoPeekTerminal.java:152) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$BaseFluxToMonoOperator.onSubscribe(Operators.java:2025) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoNext$NextSubscriber.onSubscribe(MonoNext.java:70) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.onSubscribe(FluxConcatMapNoPrefetch.java:164) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4485) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4485) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onComplete(FluxPeekFuseable.java:940) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:85) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2547) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4485) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:102) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:847) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:609) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:589) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:466) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onComplete(FluxPeekFuseable.java:277) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:357) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:294) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:371) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$BaseFluxToMonoOperator.completePossiblyEmpty(Operators.java:2071) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onComplete(FluxDefaultIfEmpty.java:134) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onComplete(FluxMap.java:275) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1840) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.signalCached(MonoCacheTime.java:337) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.onNext(MonoCacheTime.java:354) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:180) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.publisher.MonoPublishOn$PublishOnSubscriber.run(MonoPublishOn.java:181) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68) ~[reactor-core-3.5.6.jar:3.5.6]
        at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28) ~[reactor-core-3.5.6.jar:3.5.6]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
        at java.lang.Thread.run(Thread.java:833) ~[?:?]

To Reproduce Steps to reproduce the behavior: Run AppConfigurationRefresh.refreshConfigurations() when the refresh interval has passed (so the actual refresh is run).

Code Snippet

    @GetMapping("/refresh")
    public Mono<Boolean> refreshConfig() {
        return appConfigurationRefresh.refreshConfigurations();
    }

Expected behavior The configuration values should refreshed and no exception should be thrown.

Setup (please complete the following information):

Additional context We are getting some relevant warnings before the exception is thrown

2023-07-12T15:38:33.485+02:00  WARN 38804 --- [     parallel-4] c.a.c.h.HttpPipelineNextPolicy           : The pipeline switched from synchronous to asynchronous.Check if BaseAppConfigurationPolicy does not override HttpPipelinePolicy.processSync
2023-07-12T15:38:33.485+02:00  WARN 38804 --- [     parallel-4] c.a.c.h.HttpPipelineNextPolicy           : The pipeline switched from synchronous to asynchronous.Check if AddHeadersPolicy does not override HttpPipelinePolicy.processSync
2023-07-12T15:38:33.485+02:00  WARN 38804 --- [     parallel-4] c.a.c.h.HttpPipelineNextPolicy           : The pipeline switched from synchronous to asynchronous.Check if InstrumentationPolicy does not override HttpPipelinePolicy.processSync
2023-07-12T15:38:33.485+02:00  WARN 38804 --- [     parallel-4] c.a.c.h.HttpPipelineNextPolicy           : The pipeline switched from synchronous to asynchronous.Check if HttpLoggingPolicy does not override HttpPipelinePolicy.processSync
2023-07-12T15:38:34.301+02:00  WARN 38804 --- [     parallel-4] c.a.c.h.HttpPipelineNextPolicy           : The pipeline switched from synchronous to asynchronous.Check if BaseAppConfigurationPolicy does not override HttpPipelinePolicy.processSync
2023-07-12T15:38:34.302+02:00  WARN 38804 --- [     parallel-4] c.a.c.h.HttpPipelineNextPolicy           : The pipeline switched from synchronous to asynchronous.Check if AddHeadersPolicy does not override HttpPipelinePolicy.processSync
2023-07-12T15:38:34.302+02:00  WARN 38804 --- [     parallel-4] c.a.c.h.HttpPipelineNextPolicy           : The pipeline switched from synchronous to asynchronous.Check if InstrumentationPolicy does not override HttpPipelinePolicy.processSync
2023-07-12T15:38:34.302+02:00  WARN 38804 --- [     parallel-4] c.a.c.h.HttpPipelineNextPolicy           : The pipeline switched from synchronous to asynchronous.Check if HttpLoggingPolicy does not override HttpPipelinePolicy.processSync
2023-07-12T15:38:35.902+02:00  WARN 38804 --- [     parallel-4] c.a.c.h.HttpPipelineNextPolicy           : The pipeline switched from synchronous to asynchronous.Check if BaseAppConfigurationPolicy does not override HttpPipelinePolicy.processSync
2023-07-12T15:38:35.903+02:00  WARN 38804 --- [     parallel-4] c.a.c.h.HttpPipelineNextPolicy           : The pipeline switched from synchronous to asynchronous.Check if AddHeadersPolicy does not override HttpPipelinePolicy.processSync
2023-07-12T15:38:35.903+02:00  WARN 38804 --- [     parallel-4] c.a.c.h.HttpPipelineNextPolicy           : The pipeline switched from synchronous to asynchronous.Check if InstrumentationPolicy does not override HttpPipelinePolicy.processSync
2023-07-12T15:38:35.903+02:00  WARN 38804 --- [     parallel-4] c.a.c.h.HttpPipelineNextPolicy           : The pipeline switched from synchronous to asynchronous.Check if HttpLoggingPolicy does not override HttpPipelinePolicy.processSync

Information Checklist Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report

joshfree commented 1 year ago

Hi @aleksanderKopec thank you for posting this detailed issue. @mssfang will follow up with you shortly!

mssfang commented 1 year ago

@mrm9084 Can you have a look at this? It is from spring-cloud-azure-appconfiguration-config AppConfigurationRefresh

aleksanderKopec commented 1 year ago

Hello, any updates on this? It's not super high priority for now, but I would like to know if I should find some workaround.

mrm9084 commented 1 year ago

@aleksanderKopec, I have been unable to replicate the issue. I'm still trying too. If you had a sample that did it, it would help identify the issue.

mrm9084 commented 1 year ago

Ok. Was able to replicate this. A few things.

  1. Use spring-cloud-azure-appconfiguration-config, without the web, as that adds in Spring Web as a dependency and can trigger auto refresh.
  2. If you call block on on our refreshConfigurations().block() method it fixes the issue.

This is caused by the background process still running when you return already. This could work around for now, will look to see if there is a better long term fix.

aleksanderKopec commented 1 year ago

Thanks for the response.

I've tried multiple ways of adding .block() to refreshConfigurations, including running this on a Schedulers.boundedElastic() scheduler, none of them seem to work. So for example code like that doesn't work:

@GetMapping("/flag1/{flag}")
public Mono<Boolean> getFlagByName1(@PathVariable String flag, ServerWebExchange exchange) {
    appConfigurationRefresh.refreshConfigurations().block();
    return featureManager.isEnabledAsync(flag);
}

Some other things which I tried included running something akin to this:

@GetMapping("/flag1/{flag}")
public Mono<Boolean> getFlagByName1(@PathVariable String flag, ServerWebExchange exchange) {
    return Mono.just(Objects.requireNonNull(appConfigurationRefresh.refreshConfigurations().block()))
            .flatMap((ignored) -> featureManager.isEnabledAsync(flag))
            .subscribeOn(Schedulers.boundedElastic());
}

or this

@GetMapping("/flag1/{flag}")
public Mono<Boolean> getFlagByName1(@PathVariable String flag, ServerWebExchange exchange) {
    return appConfigurationRefresh.refreshConfigurations()
            .flatMap(ignored -> featureManager.isEnabledAsync(flag))
            .subscribeOn(Schedulers.boundedElastic());
}

None of the code listed before worked. I've managed to make it work though, with this code:

@GetMapping("/flag1/{flag}")
public Mono<Boolean> getFlagByName1(@PathVariable String flag, ServerWebExchange exchange) {
    return Mono.just(1)
            .flatMap(ignored -> appConfigurationRefresh.refreshConfigurations())
            .flatMap(ignored -> featureManager.isEnabledAsync(flag))
            .subscribeOn(Schedulers.boundedElastic());
}

I have no idea why this works, and the one in third code block doesn't, from my understanding they should be the same. But it seems the issue is that in other configurations the actual refresh is run on the default parallel thread pool, rather than the specified boundedElastic, and you can't run .block() on parallel thread pool.

So yeah, the workaround works for our use-case, does exactly what I expect it to do, so I guess the issue could be closed if you prefer to. But I'm pretty sure it's still a valid bug, especially the third code block seems like something that should work.

mrm9084 commented 1 year ago

@aleksanderKopec, I agree it is a bug. I was able to replicate the error, and just any block fixed it for me. What annotation are you using on the class, it may effect it.

aleksanderKopec commented 1 year ago

These are all annotations I use on the Controller

@RestController
@RequestMapping("/v1/feature-flags")
@RequiredArgsConstructor