A customer asked me for help about this.
Introduction
Windows Azure AppFabric Cache is a subset of the Windows Server 2008 R2 AppFabric distributed in-memory cache (aka “Velocity”) and typically provides it’s services for ASP.NET session provider and output caching.
Enable Cache
To speed up your web apps performance you first need to enable this Azure feature on the management portal
Click New Service Namespace –> select Cache –> select your Azure subscription (for the billing) –> the region of the data center –> and a name.
Configure Web App to use the cache
In the management portal Properties copy your host name and authentication token
to your web.config <Configuration> section:
<configSections>
<section name="dataCacheClients" type="Microsoft.ApplicationServer.Caching.DataCacheClientsSection, Microsoft.ApplicationServer.Caching.Core" allowLocation="true" allowDefinition="Everywhere"/>
</configSections>
<dataCacheClients>
<dataCacheClient name="default">
<hosts>
<host name="[SERVICE-HOST-NAME]" cachePort="22233" />
</hosts>
<securityProperties mode="Message">
<messageSecurity
authorizationInfo="[AUTHORIZATION INFO]">
</messageSecurity>
</securityProperties>
</dataCacheClient>
</dataCacheClients>
<system.web>
<sessionState mode="Custom" customProvider="AppFabricCacheSessionStoreProvider">
<providers>
<add name="AppFabricCacheSessionStoreProvider"
type="Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache"
cacheName="default"
useBlobMode="true"
dataCacheClientName="default" />
</providers>
</sessionState>
Add assembly references to the Azure libraries
Microsoft.ApplicationServer.Caching.Client.dll
Microsoft.ApplicationServer.Caching.Core.dll
Microsoft.Web.DistributedCache.dll
Microsoft.WindowsFabric.Common
Microsoft.WindowsFabric.Data.Common
2 Instances
Configure your web role to use 2 instances. Otherwise you won’t notice the problem.
Attention
Make sure, you do not confuse with the Windows Server 2008 R2 AppFabric caching libraries. Use the ones under
C:\Program Files\Windows Azure AppFabric SDK\V1.5\Assemblies\NET4.0\Cache
Access the cache from code
In the following example from the AppFabric Lab Samples, store some shopping cart entries into the session
List<string> cart = this.Session["Cart"] as List<string> ?? new List<string>();
cart.Add(selectedItem);
Session["Cart"] = cart;
and read back
var itemsInSession = this.Session["Cart"] as List<string> ?? new List<string>();
Test it
Now when I start the app and add a product to the cart, stop the compute emulator, do an iisreset.exe and refresh the page – then I still see the product. This now comes from the Azure AppFabric Cache:
on instance 1. From the debugger:
Checkout on instance deployment16(44).AzureStoreService.MVCAzureStore_IN_1
Pressing F5 to refresh the page again in the browser I suddenly don’t see the product anymore
on instance 0. From debugger
Checkout on instance deployment16(44).AzureStoreService.MVCAzureStore_IN_0
Pressing IEs F5 again and again, shows or don’t shows the product …. ?!?
Problem
So the findings are, that the session cache basically works, but not in a (load-balanced) multi-instance environment on the local development fabric compute emulator! Depending on the web role instance (0 or 1) a different session cache is used.
It looks like each web role instance is still using default ASP.NET in-proc session state, meaning you'd have different session state on each instance.
However, the session id is the same
I made sure the default in-proc session state provider is removed by commenting it and <clear/>ing the providers list:
<!--<sessionState mode="InProc" customProvider="DefaultSessionProvider">
<providers>
<add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</sessionState>-->
<!-- If session state needs to be saved in AppFabric Caching service, add the following to web.config inside system.web. If SSL is required, then change dataCacheClientName to "SslEndpoint". -->
<sessionState mode="Custom" customProvider="AppFabricCacheSessionStoreProvider">
<providers>
<clear/>
<add name="AppFabricCacheSessionStoreProvider"
type="Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache"
cacheName="default"
useBlobMode="true"
dataCacheClientName="default" />
</providers>
</sessionState>
All over again – it works in the Cloud
Not sure I did something wrong in the Lab sample – I started all over again from scratch with a simple app that stores the text box value into the Session[] state and reads it back using the buttons. Value/InstanceId/SessionID are written to the label below.
Same problem on the local fabric – BUT …
… storing from IE’s first tab the value “m5” to web role instance 0 in session 5WJJ:
Reading back from IE’s second tab the value “m5” from web role instance 1 in session 5WJJ:
gives me what I expected.
Help
As I understand this should not be the case? Seems to be an issue in the local compute emulator using the AppFabric cache service! It works in the cloud – but still makes local testing hard. Any ideas?
local compute emulator does not actually use the 'live' appfabric cache. This is a minor bug with the emulator.
ReplyDeleteAdd the application name attribute to your web.config for the correct expected behaviour.
eg
Thanks for sharing such a great blog Keep posting.
ReplyDeletedata selling companies
b2b database providers in India
database provider
indian business directory database excel
top 10 mnc in gurgaon
mnc companies in delhi gurgaon