Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
3 tasks done
aleksanderKopec opened this issue Jul 12, 2023 · 8 comments
Assignees
Labels
App Configuration Azure.ApplicationModel.Configuration Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that

Comments

@aleksanderKopec
Copy link

aleksanderKopec commented Jul 12, 2023

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):

  • OS: Windows
  • IDE: IntelliJ
  • Library/Libraries: com.azure.spring:spring-cloud-azure-appconfiguration-config:5.3.0 and com.azure.spring:spring-cloud-azure-feature-management:5.3.0
  • Java version: 17
  • App Server/Environment: Netty/Azure App Service
  • Frameworks: Spring Boot, Spring Webflux, Project Reactor

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

  • Bug Description Added
  • Repro Steps Added
  • Setup information Added
@github-actions github-actions bot added customer-reported Issues that are reported by GitHub users external to the Azure organization. needs-triage Workflow: This is a new issue that needs to be triaged to the appropriate team. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that labels Jul 12, 2023
@joshfree joshfree added Client This issue points to a problem in the data-plane of the library. App Configuration Azure.ApplicationModel.Configuration labels Jul 12, 2023
@joshfree
Copy link
Member

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

@github-actions github-actions bot removed the needs-triage Workflow: This is a new issue that needs to be triaged to the appropriate team. label Jul 12, 2023
@mssfang
Copy link
Member

mssfang commented Jul 12, 2023

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

@aleksanderKopec
Copy link
Author

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
Copy link
Member

mrm9084 commented Jul 19, 2023

@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
Copy link
Member

mrm9084 commented Jul 19, 2023

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
Copy link
Author

aleksanderKopec commented Jul 20, 2023

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
Copy link
Member

mrm9084 commented Jul 20, 2023

@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
Copy link
Author

These are all annotations I use on the Controller

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
App Configuration Azure.ApplicationModel.Configuration Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that
Projects
None yet
Development

No branches or pull requests

4 participants