Search code examples
wcfweb-servicesazureappfabricazure-caching

Azure Appfabric Caching + WCF Webservices


I have a series of WCF Web services hosted in Windows Azure and I am trying to implement appfabric caching.

I am struggling with stateless nature of web services and the need to avoid the expensive initialisation of datacachefactory and datacache objects.

I have wrapped my datacachefactory in a singleton as this seemed to be a good place to start.....

Imports Microsoft.ApplicationServer.Caching
Public Class Cache

    Private Shared _DataCacheFactory As DataCacheFactory
    Private Shared _DataCache As Microsoft.ApplicationServer.Caching.DataCache

    Private Sub New()

    End Sub


    Shared ReadOnly Property DataCacheFactory As DataCacheFactory
        Get
            If IsNothing(_DataCacheFactory) Then

                Dim localTimeout As New TimeSpan(0, 10, 0)
                Dim localCacheConfig As New DataCacheLocalCacheProperties(10000, localTimeout, DataCacheLocalCacheInvalidationPolicy.TimeoutBased)
                Dim factoryConfig As New DataCacheFactoryConfiguration()



                factoryConfig.LocalCacheProperties = localCacheConfig

                _DataCacheFactory = New DataCacheFactory(factoryConfig)

            End If

            Return _DataCacheFactory

        End Get
    End Property

    Shared ReadOnly Property DataCache As Microsoft.ApplicationServer.Caching.DataCache
        Get
            If IsNothing(_DataCache) Then
                _DataCache = DataCacheFactory.GetDefaultCache
            End If

            Return _DataCache

        End Get
    End Property

End Class

But when I try to use it, it seems to be going out of scope and is being recreated repeatedly instead of just once per azure instance. If I am understanding things correctly then this basically comes down to.....Where can I store a global variable in a wcf web service so that it doesn't go out of scope.


Solution

  • From what I can see your code should be doing what you want it to be doing. The only thing I would suggest (which has nothing to do with your problem) is to put some locking around the creation e.g. for your shortest property:

    Private Static _DataCacheLock as New Object()
    
    Shared ReadOnly Property DataCache As Microsoft.ApplicationServer.Caching.DataCache
        Get
            If IsNothing(_DataCache) Then
                 SynchLock _DataCacheLock)
                     If IsNothing(_DataCache) Then
                         _DataCache = DataCacheFactory.GetDefaultCache
                     End If
                 End SynchLock
            End If
    
            Return _DataCache
    
        End Get
    End Property
    

    It is important to have a static DataCacheFactory not only to avoid costly initialisation, but also because for each one of these objects you create uses up one of the few cache connections that you have (you only get 5 with the lowest cache size).

    Static variables will stay in scope unless the web role or the application pool gets restarted.

    How are you catching that the DataCacheFactory is being recreated?