At this year’s SQL PASS summit, I had the opportunity to talk with customers about App Fabric Cache and in preparation for the event, I put a demo to show some of the characteristics of the available APIs. The following is an explanation on how to setup the demo, what to expect when running it (as if you had attended), along with notes based on the most frequently asked questions.
For simplicity, everything will be contained on one machine. Start by downloading the appropriate Windows Server AppFabric bits and installing them and make sure to add the Caching Services, Cache Client and Cache Administrator (I would recommend installing everything so as to play with the host bits as well but nothing of that is included in this blog), see below.
After the bits are installed the configure Hosting Services window will come up, again, for simplicity, take the defaults as shown
Set the cache host with a XML configuration provider (SQL provider not use only for simplicity, SQL is however the recommended setup) and a small cluster. Make sure the service account has rights to the XML share, as follows. If you have ran the wizard on the same share before you will have to remove the existing ClusterConfig.xml file (or rename it)
Leave all ports as per defaults (see below).
for more installation details see Install Windows Server AppFabric and Configure Windows Server AppFabric.
NOTE: Do not try to setup either a client or server by copying and GACing the App Fabric Cache DLLs, this will lead to errors and is not a supported installation.
Now that the cache host is setup and configured, run the “Caching Administration Windows PowerShell” in elevated rights, as an Administrator. And to start the cache host, run the following command.
You will be prompted for the hostname and cache port. Give the machine name and port 22233 (since the defaults were taken when running the configuration wizard), you should see the following
HostName : CachePort Service Name Service Status Version Info
-------------------- ------------ -------------- ------------
jaimelap2:22233 AppFabricCachingService UP 1 [1,1][1,1]
Setup your user account to an allowed client user, in my case I had
Create the cache for the demo application and look at the current statistics
You will see the following stats since nothing has yet taken place:
Size : 0
ItemCount : 0
RegionCount : 0
RequestCount : 0
MissCount : 0
Here is the demo project (built in VS2010 ultimate), make sure the two following references are correctly set, otherwise your setup may be incorrect, refer to this blog for troubleshooting hints.
Running the solution will show the following windows form:
This is the most commonly use APIs, as per the message in the Status text start by adding an object,
At this point go back to the “Caching Administration Windows PowerShell” console and type:
The RequestCount will be 1, this is the new added object had just got added
The Add API can be thought as a type of insert statement but it only takes a key value pair. Note that the Get API merely retrieved whatever it found in the object in an optimistic manner, it did not care if it was changed by any other process, as it retrieved the latest version.
If you want to know when an object has changed from the last time it was retrieved then GetIfNewer is a good option. Looking at the code in the solution, when the Get API was executed (in line 134 of form1.cs) a DataCacheItemVersion was also collected, this can be thought of as a type of version for the gotten item. See line 143 in Form1.cs
RetrievedStrFromCache = (string)myDefaultCache.Get(myKey, out myVersionBeforeChange)
For simplicity, say it is retrieved as Version1, if another process comes and does a Put against the same item (by using the same key) then it will change its version to say Version2, in the same way the DataCacheItemVersion will get updated. GetIfNewer can be used to leverage this type of versioning, by using the DataCacheItemVersion retrieved in the Get API in the GetIfNewer API, it will know to return a NULL object if it finds an object with the same DataCacheItemVersion in cache, otherwise it will return the new (updated) object.
Go back to the demo form,
Similarly, if GetIfNewer is executed after doing a Remove and an Add, it will also retrieve an object since these two operations (Remove and Add) will have, in effect, modified the object.
As explained, the Get API does an optimistic retrieval but there are cases when a pessimistic retrieval may be preferred. This scenario will be most adequately use for Resource data (shared reads & writes across multiple users). For those cases, the GetAndLock API will allow locking an object for a given period of time; the demo does it for 5 seconds. Two other things to keep in mind are the key and the DataCacheLockHandle, as these are needed to handle the locking semantics.
Running the demo:
The PutAndUnlock button will also correctly unlock the object but, as stated by its name, it will update the object at the same time.
NOTE: the Put button will override the lock semantics; that is, the object will be unlock and update without requiring a DataCacheLockHandle. This is because the intent with the lock APIs is for all applications to honor it, so in order for the locking to be honored, it is incumbent upon the clients to be using the Lock methods since not using them will override the locking guarantees.
This demo goes over the ability to locally cache objects, this will save a round trip to the cache cluster, and in essence, it will eliminate the network delay to and back from the cache server.
To start the demo start the “Caching Administration Windows PowerShell” tool and run the following commands
The purpose here is to clean all the objects currently cache; the statistics results should show all zeros.
Note that if you do a GetIfNewer instead of a Get, the requestCount will increase; this is because GetIfNewer cannot be locally supplied, as it needs to check with all the other cache hosts (in this case, the XML configuration provider).
To achieved the demonstrated, two DataCacheFactories are leverage - see line 54~59 in form1.cs. The DataCacheFactory named “myCacheFactory” is the one use for non-local cache and the one named “myCacheFactory_LC” is the one setup for local cache, its configuration property is defined in line 57, as follows.
//Create the local cache cacheFactory constructor, kept for 5 min.
configuration.LocalCacheProperties = new DataCacheLocalCacheProperties(1000, new TimeSpan(0, 5, 0), DataCacheLocalCacheInvalidationPolicy.TimeoutBased);
Note that the timeout is setup to 5 minutes, to demo it,
Reviewed by: Christian Martinez and Mark Simms