2

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.

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
David Steele
  • 3,433
  • 21
  • 23

3 Answers3

2

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?

knightpfhor
  • 9,299
  • 3
  • 29
  • 42
  • Thanks I have added this. It was precisely because I was running out of connections and getting an error that made me think that this was going out of scope. I will let you all know in a bit. – David Steele Jul 03 '11 at 23:34
  • You'll also want to make sure that you properly dispose of the DataCacheFactory when you application stops to make sure it releases the connection properly and also use the April Update to the app fabric SDK (released 2001-07-01) because it has a fix regarding releasing connections – knightpfhor Jul 03 '11 at 23:52
  • I am marking this as the answer because it did solve the connection issues. I have however reverted to httpruntime.cache. After trying this out it didn't seem to make any difference to the app and was perhaps a little slower. Thank you everybody for all your help. – David Steele Jul 04 '11 at 07:00
  • ps I will look at this again when I want to introduce more caching but for now I am not caching a lot so am ok with the existing cache. – David Steele Jul 04 '11 at 07:01
0

Add a check to the constructor of your service. If the dataCache object is empty, initialize it, otherwise, don't.

Frode Stenstrøm
  • 1,048
  • 7
  • 24
0

If you are using multiple services, the shared keyword will not do you much good. Look at this answer. Multiple processes will have multiple/separate AppDomains. I am not sure how the AppDomain is activated by the IIS host though, you should check that out.

P.S.: Your question isn't really clear. What do you mean by a global variable? Something that all processes can see? What does Azure's stateless nature have to do with this? That means something completely different.

Community
  • 1
  • 1
Anže Vodovnik
  • 2,325
  • 16
  • 25
  • I was running out of connections and wasnt too sure about the lifetime of the singleton in the case of a web service. – David Steele Jul 03 '11 at 23:39