F# interactive, AppFabric cache and PowerShell (Part 2)

By Petr at July 15, 2010 03:51
Filed Under:

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
  1. #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
  1. #r @"C:\Projects\Velocity4\Microsoft.ApplicationServer.Caching.Core.dll"
  2. #r @"C:\Projects\Velocity4\Microsoft.ApplicationServer.Caching.Client.dll"
  3. #r @"C:\Projects\Velocity4\Microsoft.ApplicationServer.Caching.Management.dll"
  4. #r @"C:\Projects\Velocity4\Microsoft.ApplicationServer.Caching.ManagementPS.dll"
  5. #r @"C:\Projects\Velocity4\Microsoft.ApplicationServer.Caching.Configuration.dll"
  6.  

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
  1. open System
  2. open Microsoft.ApplicationServer.Caching
  3.  
  4. let createDataCacheFactory =
  5. let config = DataCacheFactoryConfiguration()
  6. config.LocalCacheProperties <- DataCacheLocalCacheProperties() // use local cache in the cache client
  7. config.Servers <- [DataCacheServerEndpoint(Environment.MachineName, 22233)]
  8. new DataCacheFactory(config)
  9.  
  10. let createCacheClient cacheName =
  11. let factory = createDataCacheFactory
  12. 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
  1. let putData (cache: DataCache) key value (region: string) =
  2. cache.Put(key, value, region)
  3.  
  4. let getData (cache: DataCache) key (region: string) =
  5. cache.Get(key, region)
  6.  
  7. let removeData (cache: DataCache) key (region: string) =
  8. cache.Remove(key, region)
  9.  
  10. let createRegion (cache: DataCache) regionName =
  11. cache.CreateRegion regionName
  12.  
  13. let removeRegion (cache: DataCache) regionName =
  14. cache.RemoveRegion regionName
  15.  
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
  1. // Creating cache client for our named cache:
  2. let cacheClient = createCacheClient "MyCache"
  3. // Creating the region to store data
  4. createRegion cacheClient "TestRegion"
  5. // Creating simple test data
  6. let testData = seq {
  7. for i in 1 .. 10000 do
  8. yield (sprintf "key%d" i , sprintf "data%d" i) }
  9. // Populate our cache region
  10. testData |> Seq.iter (fun (fst, snd) -> putData cacheClient fst snd "TestRegion"|> ignore)
  11.  
  12. // Retrieve and print all data:
  13. let getAllData =
  14. for i in 1 .. 10000 do
  15. let key = sprintf "key%i" i
  16. let d = getData cacheClient key "TestRegion"
  17. printfn "GotData: key:%s, value: %A" key d
  18.  
  19. // We can play with different ways to get these data.
  20.  
  21. open Microsoft.FSharp.Control;
  22.  
  23. let getAllDataMap testData =
  24. testData |> Seq.map (fun (fst, _) -> getData cacheClient fst "TestRegion" )
  25.  
  26. let getAllDataParallel testData =
  27. testData |> Seq.map (fun (fst, _) -> async { return getData cacheClient fst "TestRegion" })
  28. |> Async.Parallel
  29. |> Async.RunSynchronously
  30.  
  31. // And remove them from cache finally:
  32. for i in 1 .. 10000 do
  33. let key = sprintf "key%i" i
  34. removeData cacheClient key "TestRegion" |> ignore
  35.  
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.

F# interactive, AppFabric cache and PowerShell (Part 1)

By Petr at July 14, 2010 03:29
Filed Under:

Usually you can improve performance and scalability of distributed application using in-memory cache data. Windows Server AppFabric recently released by Microsoft includes distributed cache module formerly known under codename “Velocity”. It is a distributed in-memory application cache platform for developing scalable, available, and high-performance applications. AppFabric fuses memory across multiple computers to give a single unified cache view to applications. Applications can store any serializable CLR object without worrying about where the object gets stored. Scalability can be achieved by simply adding more computers on demand. The cache also allows for copies of data to be stored across the cluster, thus protecting data against failures. It runs as a service accessed over the network.

Installation and configuration went very smoothly, Microsoft documentation on setup and configuration is quite good.

I set up AppFabric on my laptop running 64-bit version of Windows 7 without any problems.

I planned to play with Cache API using F# interactive – a great tool available in Visual Studio 2010 allowing quickly prototype and test F# code.

Data stored in AppFabric cache are partitioned using named memory caches which could be created by PowerShell commands – PowerShell is the main tool for AppFabric administration tasks. Strangely enough PowerShell command is the only way to create new named cache on the server (there is no .NET API for this purpose) so I had to learn how to call PowerShell commands from F#. After some googling I found the great blog post by Stephen Kaufman “Calling PowerShell from .NET” which had exactly what I needed but he used C#. Both C# and F# are .NET languages so it shouldn’t be very hard to translate code from one to another. So I created a couple of functions to call PowerShell commands from F# and tried them in F# interactive.

 

F#, using GeSHi 1.0.8.8
  1. // We need to refer PowerShell API assembly
  2. #r @"C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll"
  3.  
  4. open System.Management.Automation
  5. open System.Management.Automation.Runspaces
  6.  
  7. let invokePsCacheCommand cmdName (parNameVal: (string * obj) list) =
  8. let state = InitialSessionState.CreateDefault()
  9. // Import PowerShell AppFabric modules
  10. [|"DistributedCacheAdministration"; "DistributedCacheConfiguration"|] |> state.ImportPSModule
  11. state.ThrowOnRunspaceOpenError <- true
  12. let rs = RunspaceFactory.CreateRunspace(state)
  13. rs.Open()
  14. // Create PowerShell command pipeline
  15. let pipe = rs.CreatePipeline()
  16. pipe.Commands.Add(Command("Use-CacheCluster"))
  17. let cmd = new Command(cmdName)
  18. // Add command parameters as name-value pairs
  19. parNameVal |> List.iter (fun (name, value) -> cmd.Parameters.Add(CommandParameter(name, value)))
  20. pipe.Commands.Add(cmd)
  21. // And invoke commands
  22. pipe.Invoke()
  23.  
  24. let createCache cacheName =
  25. [("Name", cacheName);
  26. ("Expirable", box false)] |> invokePsCacheCommand "New-Cache"
  27.  
  28. let removeCache cacheName =
  29. [("Name", cacheName)] |> invokePsCacheCommand "Remove-Cache"
  30.  
  31. let exportCacheConfig fileName =
  32. [("File", fileName)] |> invokePsCacheCommand "Export-CacheClusterConfig"
  33.  
Parsed in 0.026 seconds at 51.22 KB/s

 

Now I can try to create my first named cache from F# interactive:

 

createCache "MyCache"

 

I selected this string and hit Alt-Enter to execute it in F# Interactive window and immediately got a cryptic message: “The specified module 'DistributedCacheAdministration' was not loaded because no valid module file was found in any module directory.” After a short internet search I found this post by Ron Jacobs. It seems that I’ve got this error because I’m using 64-bit version of AppFabric but VisualStudio runs Fsi.exe as 32-bit process. Am I out of lack and cannot use F# interactive to run PowerShell commands? No. It seems that in quickly expanding F# community one can find the answer to almost any problem:) Here it is: “Making the FSharp interpreter (fsi) run in 64bit!” I made all woodoo magic procedures described in this article and finally got sweet picture in power shell command window:

 

FsiCache

 

In the next part I’ll describe how to use cache API to store and retrieve data using F#.

Programming Language Concepts for Software Developers

By Petr at June 27, 2010 01:59
Filed Under:

 

IT University of Copenhagen uses F# as presentation language in a course “Programming Language Concepts for Software Developers

Link to the course material (textbook, presentations and exercises):

http://www.itu.dk/courses/BPRD/E2009/

F# User Group meeting

By Petr at June 27, 2010 01:58
Filed Under:

It was pretty cool. Steffen Forkmann spoke from Germany for groups here in Boston and New Orleans (at TechEd 2010). Looks like F# is almost ideal for creating DSLs. Discovered new F# feature which allows create functions like this: 

  let ``function name with spaces и всяческим уникодом`` num =

      printfn "Output from the function %d" num  

Just wrap the arbitrary string by double ticks `` – and it will be perfectly legal F# identifier!

Fsi output: val ( function name with spaces и всяческим уникодом ) : int -> unit

> ``function name with spaces и всяческим уникодом`` 45;; Output from the function 45 val it : unit = () >

More about F# event performance

By Petr at June 27, 2010 01:56
Filed Under:

Struggling to Put New Wine into Old Wineskins

By Petr at June 27, 2010 01:55
Filed Under:

New England F# User Group Monthly Meeting

By Petr at June 27, 2010 01:53
Filed Under:

New England F# User Group

Our next meeting will take place on Monday, June 7th from 6:30pm to 8:30pm!
All interested are welcome to join us. 

Speaker: Steffen Forkmann, author of FAKE and NaturalSpec 

Steffen is the author of the two open source F# projects "FAKE - F# Make" (http://bitbucket.org/forki/fake/wiki/Home) and "NaturalSpec" (http://bitbucket.org/forki/naturalspec/wiki/Home).  In this talk, he shows these tools in action, and talks a bit about some internal implementation details. In particular he shows why he used F# and how specific language constructs help to simplify the usage.

Steffen Forkmann is currently a developer for msu solutions GmbH in Hamburg (Germany), where he helps to develop a large accounting system based on Microsoft Dynamics NAV. In addition to his day job, he has a deep interest in functional programming and in particular in F#. You can find him on his blog at http://www.navision-blog.de.

Microsoft Research New England
First Floor Conference Center
One Memorial Drive
Cambridge, MA 02142


Rick Minerich on event performance in F# and C#

By Petr at June 27, 2010 01:52
Filed Under:

Fun with Fibonacci

By Petr at June 27, 2010 01:49
Filed Under:
1) Naive implementation:

 

F#, using GeSHi 1.0.8.6
  1. let rec fibnaive n =
  2.     if n < 2 then 1I
  3.     else
  4.         fibnaive (n - 1) + fibnaive (n - 2)
  5.  
Parsed in 0.008 seconds at 11.48 KB/s

 

Horrible performance. fibnaive 40 took 16.6 sec on my laptop
 

2) Matrix algorithm:

It’s handy that F# have matrix type in Microsoft.FSharp.Math namespace.

The type matrix uses float numbers. Let’s see how we could calculate Fibonacci’s:


F#, using GeSHi 1.0.8.6
  1. open Microsoft.FSharp.Math
  2. let matrixd = matrix [ [ 1.; 1. ];[ 1.; 0. ] ]
  3. let rec fibmatd n =
  4. if n < 2 then matrixd
  5. else matrixd * fibmatd(n - 1)
  6. let fib n =
  7. if n < 2 then 1I
  8. else
  9. let m = fibmatd n
  10. System.Numerics.BigInteger(m.[1, 0])
  11.  
Parsed in 0.013 seconds at 21.61 KB/s

Result of fib 1000:

Real: 00:00:00.002, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
val it : System.Numerics.BigInteger =
4346655768693742750699615555111373698901493060675
3135940421893445574924103291704556590724031629457
1302242425620098031386057959852750558837247446456
7001785294423082188544814790061823421628580750638
3791353495552

It’s pretty fast but it has a problem: if I remember correctly Fibonacci of 1000, it calculates only first 15 digits right.

3) Generic matrix:

But this namespace has generic version of matrix type – we can use any arbitrary type to construct our matrix. We would use BigInteger to get a correct results.
 

F#, using GeSHi 1.0.8.6
  1. open Microsoft.FSharp.Math
  2. let anymatrix = Matrix.Generic.ofList
  3. let fibceed = anymatrix [ [ 1I; 1I ];[ 1I; 0I ] ]
  4. let rec fibmat n =
  5. if n < 2 then fibceed
  6. else fibceed * fibmat(n - 1)
  7. let fib n =
  8. if n < 2 then 1I
  9. else
  10. let m = fibmat n
    m.[0, 1]
  11.  
Parsed in 0.012 seconds at 23.16 KB/s

Now the result of fib 1000:
Real: 00:00:00.006, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
val it : System.Numerics.BigInteger =
4346655768693745643568852767504062580256466051737
1780402481729089536555417949051890403879840079255
1692959225930803226347752096896232398733224711616
4299644090653318793829896964992851600370447613779
5166849228875

It’s slightly slower but it calculates Fibonacci of 1000 correctly.

4) Another algorithm:


F#, using GeSHi 1.0.8.6
  1. let rec fibb (n1: bigint) (n2: bigint) c =
  2. if c = 1 then
  3. n2
  4. else
  5. fibb n2 (n1+n2) (c-1)
  6.  
  7. let fibfast num =
  8. (fibb 1I 1I (num - 1))
  9.  
Parsed in 0.009 seconds at 17.89 KB/s

It’s results are so far fastest I could get:

Real: 00:00:00.001, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0

val it : bigint =
4346655768693745643568852767504062580256466051737
1780402481729089536555417949051890403879840079255
1692959225930803226347752096896232398733224711616
4299644090653318793829896964992851600370447613779
5166849228875

And it’s tail recursive so we can play with it up to OutOfMemory exception for very very big integers. I’m always wanted to know what would be Fibonacci of 1000000. And now I can get it in slightly more than 2 min:

Real: 00:02:06.986, CPU: 00:02:10.229, GC gen0: 18414, gen1: 2523, gen2: 395
I don’t put it here because it consists of 208993 digits, but it starts with:

19532821287077577316320149475962563324435…
 

5) And finally using Seq type:

F#, using GeSHi 1.0.8.6
  1. let fibonacci =
  2. Seq.unfold
  3. (fun (current, next) -> Some(current, (next, current + next)))
    (0I, 1I)
  4.  
  5. let term n= fibonacci |> Seq.take n
  6. let fib 1000 = Seq.nth 1000 (term 1001)
  7.  
Parsed in 0.012 seconds at 17.07 KB/s

It’s also pretty fast. Here are results of calculating 1000 Fibonacci numbers:
Real: 00:00:00.001, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0

If anyone have another interesting algorithm to share – welcome to comments!


XML, Linq and F#

By Petr at June 27, 2010 01:47
Filed Under:

Here I want to test how to post code snippets to this community. As an example I put here code from “F# Expert” book. I'm using Live Writer with GeSHi plugin for syntax highlighting.

The sample shows how using higher order functions and Linq we can easily and elegantly create XML documents.

F#, using GeSHi 1.0.8.6
  1. open System.Xml.Linq
  2.  
  3. let xml =
  4. "<contacts>
  5. <contact>
  6. <name>John Smith</name>
  7. <phone type=\"home\">+1 626-123-4321</phone>
  8. </contact>
  9. </contacts>"
  10. let doc1 = XDocument.Parse xml
  11.  
  12. let xname n = XName.op_Implicit(n)
  13. let xdoc (el:seq<XElement>) = new XDocument(Array.map box (Array.ofSeq el))
  14. let xelem s el = new XElement(xname s, box el)
  15. let xatt a b = new XAttribute(xname a, b) |> box
  16. let xstr s = box s
  17.  
  18. let doc =
  19. xdoc
  20. [xelem "contacts"
  21. [xelem "contact"
  22. [(xelem "name" (xstr "John Smith"))
  23. (xelem "phone"
  24. [xatt "type" "home"
    xstr "+1 626-123-4321"])
  25. ]
  26. ]
  27.   ]
Parsed in 0.022 seconds at 34.35 KB/s