You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
My app is hosted on Azure, and I already use Azure Service Bus and Cosmos DB. Since Azure Redis is costly and my app doesn’t require its level of performance, I’m exploring Cosmos DB for distributed caching and Azure Service Bus as a backplane.
From my research, it seems that Redis is the only officially supported backplane implementation, and I couldn't find an existing implementation using Azure Service Bus.
Questions:
Does using Azure Service Bus as a backplane make sense?
Would there be any drawbacks compared to Redis?
My Implementation
I started working on a Service Bus-based backplane, but I have some concerns—particularly with the Subscribe method.
Here’s my current (dummy/basic/work-in-progress) implementation:
usingAzure.Messaging.ServiceBus;usingAzure.Messaging.ServiceBus.Administration;usingZiggyCreatures.Caching.Fusion;usingZiggyCreatures.Caching.Fusion.Backplane;namespaceZiggyCreatures.FusionCache.Backplane.AzureServiceBus{publicclassServiceBusBackplane:IFusionCacheBackplane{privateconstStringtopicName="fusionCache-dev";publicServiceBusBackplane(ServiceBusAdministrationClientserviceBusAdministrationClient,ServiceBusClientserviceBusClient){this._serviceBusAdministrationClient=serviceBusAdministrationClient;this._serviceBusClient=serviceBusClient;this._serviceBusSender=newLazy<ServiceBusSender>(()=>{returnthis._serviceBusClient.CreateSender(topicName);});}privatereadonlyServiceBusAdministrationClient_serviceBusAdministrationClient;privatereadonlyServiceBusClient_serviceBusClient;privatereadonlyLazy<ServiceBusSender>_serviceBusSender;privateServiceBusProcessor_serviceBusProcessor;publicvoidPublish(BackplaneMessagemessage,FusionCacheEntryOptionsoptions,CancellationTokentoken=default){this.PublishAsync(message,options,token).GetAwaiter().GetResult();}publicasyncValueTaskPublishAsync(BackplaneMessagemessage,FusionCacheEntryOptionsoptions,CancellationTokentoken=default){awaitthis._serviceBusSender.Value.SendMessageAsync(newServiceBusMessage(){Body=newBinaryData(BackplaneMessage.ToByteArray(message))},token);}publicvoidSubscribe(BackplaneSubscriptionOptionsoptions){this.SubscribeAsync(options).GetAwaiter().GetResult();}publicvoidUnsubscribe(){this.UnsubscribeAsync().GetAwaiter().GetResult();}privateasyncTaskSubscribeAsync(BackplaneSubscriptionOptionsoptions){if(!awaitthis._serviceBusAdministrationClient.TopicExistsAsync(topicName)){awaitthis._serviceBusAdministrationClient.CreateTopicAsync(topicName);}varsubcriptionName=$"fusion-{options.CacheInstanceId}";if(!awaitthis._serviceBusAdministrationClient.SubscriptionExistsAsync(topicName,subcriptionName)){awaitthis._serviceBusAdministrationClient.CreateSubscriptionAsync(topicName,subcriptionName);}this._serviceBusProcessor=this._serviceBusClient.CreateProcessor(topicName,subcriptionName);this._serviceBusProcessor.ProcessErrorAsync+=async(args)=>{// TODO};this._serviceBusProcessor.ProcessMessageAsync+=async(args)=>{vardata=args.Message.Body.ToArray();varmsg=BackplaneMessage.FromByteArray(data);if(options.IncomingMessageHandlerAsync!=null){awaitoptions.IncomingMessageHandlerAsync(msg);}};awaitthis._serviceBusProcessor.StartProcessingAsync();}privateasyncTaskUnsubscribeAsync(){awaitthis._serviceBusProcessor.StopProcessingAsync();awaitthis._serviceBusProcessor.DisposeAsync();// TODO delete subscription }}}
Concerns
Subscribe Method and Sync-over-Async Pattern
The Subscribe method is synchronous, which forces me to use a sync-over-async pattern (.GetAwaiter().GetResult()). I’d like to avoid this because it can lead to deadlocks or thread pool exhaustion in certain scenarios.
Is there a specific reason why this method is sync-only?
Would it make sense to introduce an async version of this method?
I checked the Redis-based backplane and noticed similar concerns — was there a design decision behind this?
Unsubscribe Method Behavior
I noticed that in the FusionCache Simulator App, the Unsubscribe method is never triggered.
Is this expected behavior?
If so, how does FusionCache typically handle backplane unsubscription?
Next Steps
If this approach makes sense, I’m happy to open a Pull Request (PR) to contribute this as an alternative backplane provider for FusionCache.
Would love to hear your thoughts! 🚀
The text was updated successfully, but these errors were encountered:
cyrildurand
changed the title
Discussion: Implementing a FusionCache Backplane with Azure Service Bus
[Discussion] Implementing a FusionCache Backplane with Azure Service Bus
Jan 30, 2025
Hi @cyrildurand
I'll answer about the first part later, but for now:
Concerns
Subscribe Method and Sync-over-Async Pattern
The Subscribe method is synchronous, which forces me to use a sync-over-async pattern (.GetAwaiter().GetResult()). I’d like to avoid this because it can lead to deadlocks or thread pool exhaustion in certain scenarios.
[...]
You're right about this, and in fact since last week I've been working exactly on this.
Mind you, this never cause any issue that I'm aware of, but still it would be better to go full-async on all the code paths.
The next version (coming out very soon) will have this change in it.
My app is hosted on Azure, and I already use Azure Service Bus and Cosmos DB. Since Azure Redis is costly and my app doesn’t require its level of performance, I’m exploring Cosmos DB for distributed caching and Azure Service Bus as a backplane.
From my research, it seems that Redis is the only officially supported backplane implementation, and I couldn't find an existing implementation using Azure Service Bus.
Questions:
My Implementation
I started working on a Service Bus-based backplane, but I have some concerns—particularly with the
Subscribe
method.Here’s my current (dummy/basic/work-in-progress) implementation:
Concerns
Subscribe
Method and Sync-over-Async PatternThe
Subscribe
method is synchronous, which forces me to use a sync-over-async pattern (.GetAwaiter().GetResult()
). I’d like to avoid this because it can lead to deadlocks or thread pool exhaustion in certain scenarios.Unsubscribe
Method BehaviorI noticed that in the FusionCache Simulator App, the
Unsubscribe
method is never triggered.Next Steps
If this approach makes sense, I’m happy to open a Pull Request (PR) to contribute this as an alternative backplane provider for FusionCache.
Would love to hear your thoughts! 🚀
The text was updated successfully, but these errors were encountered: