In previous post I wrote how to invoke AppFabric management PowerShell commands from F# interactive. Now we successfully created named cache in AppFabric distributed cache and I want to use AppFabric cache API to store and retrieve data from this cache. You can structure data stored in named cache using cache regions (which roughly correspond to tables in relational database). Data could be stored in the region using string keys which work as in usual hashtable.
But first of all you need to find out how to refer to AppFabric API assemblies in F# project. MSDN documentation tells the following: “On 64-bit operating systems, the AppFabric directory will not be directly visible. To work around this problem, replace the System32 directory name with the name SysNative. This results in navigating to the C:\Windows\SysNative\AppFabric directory in this step”. So I added a reference to these assemblies in my F# script file:
F#, using GeSHi 1.0.8.8
#r @"C:\Windows\SysNative\AppFabric\Microsoft.ApplicationServer.Caching.Core.dll"
Parsed in 0.007 seconds at 11.99 KB/s
So far all looks OK, but when I selected this line and sent it to FSI window I’ve got this error message:
“error FS0084: Assembly reference 'C:\Windows\SysNative\AppFabric\Microsoft.ApplicationServer.Caching.Core.dll' was not found or is invalid”. I tried to search for this message but didn’t found any workaround. (It’s strange because this exact reference works perfectly when I added it to the project, but it still gives me an error in FSI window). To make it work in FSI I had to copy all needed AppFabric assemblies to the usual folder I created on my hard drive and refer to these copied assemblies from script file. It’s kind of ugly but it seems to work. So my references in script look like this:
F#, using GeSHi 1.0.8.8
#r @"C:\Projects\Velocity4\Microsoft.ApplicationServer.Caching.Core.dll"
#r @"C:\Projects\Velocity4\Microsoft.ApplicationServer.Caching.Client.dll"
#r @"C:\Projects\Velocity4\Microsoft.ApplicationServer.Caching.Management.dll"
#r @"C:\Projects\Velocity4\Microsoft.ApplicationServer.Caching.ManagementPS.dll"
#r @"C:\Projects\Velocity4\Microsoft.ApplicationServer.Caching.Configuration.dll"
Now I could use cache API.First of all we need to create DataCacheFactory object and DataCache client. (By the way MSDN has pretty good documentation on Windows Server AppFabric Caching Concepts and Architecture)
F#, using GeSHi 1.0.8.8
open System
open Microsoft.ApplicationServer.Caching
let createDataCacheFactory =
let config = DataCacheFactoryConfiguration()
config.LocalCacheProperties <- DataCacheLocalCacheProperties() // use local cache in the cache client
config.Servers <- [DataCacheServerEndpoint(Environment.MachineName, 22233)]
new DataCacheFactory(config)
let createCacheClient cacheName =
let factory = createDataCacheFactory
cacheName |> factory.GetCache
Parsed in 0.016 seconds at 29.76 KB/s
Now we can use DataCache object to manipulate data in our cache (I will not describe or implement complete cache API here but rather illustrate main concepts):
F#, using GeSHi 1.0.8.8
let putData (cache: DataCache) key value (region: string) =
cache.Put(key, value, region)
let getData (cache: DataCache) key (region: string) =
cache.Get(key, region)
let removeData (cache: DataCache) key (region: string) =
cache.Remove(key, region)
let createRegion (cache: DataCache) regionName =
cache.CreateRegion regionName
let removeRegion (cache: DataCache) regionName =
cache.RemoveRegion regionName
Parsed in 0.016 seconds at 27.77 KB/s
So we can now create some simple test data and test our F# API wrapper:
F#, using GeSHi 1.0.8.8
// Creating cache client for our named cache:
let cacheClient = createCacheClient "MyCache"
// Creating the region to store data
createRegion cacheClient "TestRegion"
// Creating simple test data
let testData = seq {
for i in 1 .. 10000 do
yield (sprintf "key%d" i , sprintf "data%d" i) }
// Populate our cache region
testData
|> Seq.
iter (fun (fst,
snd) -> putData cacheClient
fst snd "TestRegion"|> ignore)
// Retrieve and print all data:
let getAllData =
for i in 1 .. 10000 do
let key = sprintf "key%i" i
let d = getData cacheClient key "TestRegion"
printfn "GotData: key:%s, value: %A" key d
// We can play with different ways to get these data.
open Microsoft.FSharp.Control;
let getAllDataMap testData =
testData
|> Seq.
map (fun (fst, _
) -> getData cacheClient
fst "TestRegion" )
let getAllDataParallel testData =
testData
|> Seq.
map (fun (fst, _
) -> async { return getData cacheClient
fst "TestRegion" }) |> Async.Parallel
|> Async.RunSynchronously
// And remove them from cache finally:
for i in 1 .. 10000 do
let key = sprintf "key%i" i
removeData cacheClient key "TestRegion" |> ignore
Parsed in 0.028 seconds at 41.63 KB/s
So now we can use PowerShell AppFabric management commands from F# and use cache API to put and get simple data. Next time I’m going to play with more advanced cache API (notifications etc.) and real database data.