Advertisement
Guest User

F# Caching System

a guest
Jan 31st, 2016
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 4.99 KB | None | 0 0
  1. namespace FSharpTools
  2. open System.Web
  3. open System.Web.Caching
  4. open System.Collections;
  5. open Microsoft.FSharp.Reflection
  6.  
  7. //Modules are equivalent, machine code wise, to a static class in C#
  8. //So any methods defined in here should be callable as
  9. //TheOneCache.methodname
  10. //as long as the source file is using FsharpTools namespace
  11. module TheOneCache =
  12.  
  13.     type CacheType = Web | Redis
  14.  
  15.     //The ICache interface, which can be implemented for IIS cache, Redis, etc
  16.     type ICache =
  17.         abstract member Add: string -> 'T -> unit
  18.        abstract member AddForTime: string -> 'T -> System.TimeSpan -> unit
  19.         abstract member Get: string -> 'T option
  20.        abstract member Exists: string -> bool
  21.        abstract member Remove: string -> unit
  22.        abstract member FlushAll: unit
  23.        abstract member FlushKeysThatStartWith: string -> unit                      
  24.        abstract member GetCountStartsWith: string -> int
  25.        abstract member GetCacheType: CacheType
  26.  
  27.    //Implement the ICache interface as an IIS cache using an object expression
  28.    let WebCache =
  29.        {   new ICache with
  30.            
  31.            member this.Add key value =
  32.                HttpRuntime.Cache.Insert(key, value, null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Normal, null)                            
  33.            
  34.            member this.AddForTime key value duration =
  35.                HttpRuntime.Cache.Insert(key, value, null, System.Web.Caching.Cache.NoAbsoluteExpiration, duration, CacheItemPriority.NotRemovable, null)                            
  36.            
  37.            member this.Get<'T> key =
  38.                  match HttpRuntime.Cache.Get(key) with
  39.                  | null -> None
  40.                  | result -> Some (result :?> 'T)
  41.  
  42.            member this.Exists key =
  43.                match HttpRuntime.Cache.Get(key) with
  44.                | null -> false
  45.                | result -> true
  46.            
  47.            member this.Remove key =
  48.                HttpRuntime.Cache.Remove(key)  |> ignore        
  49.            
  50.            //IIS cache object uses a weird enumerator that is not F# friendly
  51.            //So we have some imperative code
  52.            member this.FlushAll =                
  53.                let enumerator = HttpRuntime.Cache.GetEnumerator()
  54.                while enumerator.MoveNext() do
  55.                    HttpRuntime.Cache.Remove(enumerator.Key.ToString()) |> ignore
  56.            
  57.            member this.FlushKeysThatStartWith keyPrefix =                
  58.                let enumerator = HttpRuntime.Cache.GetEnumerator()
  59.                while enumerator.MoveNext() do
  60.                    match enumerator.Key.ToString().StartsWith(keyPrefix) with
  61.                    | true -> HttpRuntime.Cache.Remove(enumerator.Key.ToString()) |> ignore
  62.                    | false -> ()
  63.                                                                
  64.            //Oh no...mutable!
  65.            member this.GetCountStartsWith keyPrefix =
  66.                let enumerator = HttpRuntime.Cache.GetEnumerator()
  67.                let mutable counter = 0
  68.                while enumerator.MoveNext() do
  69.                    match enumerator.Key.ToString().StartsWith(keyPrefix) with
  70.                    | true -> counter <- counter + 1
  71.                    | false -> ()
  72.                counter
  73.  
  74.            member this.GetCacheType =
  75.                CacheType.Web
  76.        }
  77.  
  78.    
  79.    //Our list of caches, for now just the IIS cache
  80.    let caches = [WebCache]
  81.    
  82.    //prints a union name as a string
  83.    let unionToString (x:'a) =
  84.         match FSharpValue.GetUnionFields(x, typeof<'a>) with
  85.        | case, _ -> case.Name
  86.  
  87.    //Like an enum
  88.    type EntryType = Marklogic | SQL | Netsuite | Other with
  89.        member this.ToString = unionToString this
  90.  
  91.  
  92.    //No need for objects, just functions
  93.    let Add (entryType:EntryType, key, value) =
  94.        caches |> List.iter (fun c -> c.Add (entryType.ToString + key) value )
  95.  
  96.    let AddForTime(entryType:EntryType, key, value, duration) =
  97.        caches |> List.iter (fun c-> c.AddForTime (entryType.ToString + key) value duration)
  98.  
  99.    let Get<'T> (entryType:EntryType, key) =
  100.         caches |> List.tryPick (fun c -> c.Get (entryType.ToString + key))
  101.    
  102.     let Exists (entryType:EntryType, key) =
  103.         caches |> List.exists(fun c -> c.Exists (entryType.ToString + key) = true)
  104.    
  105.     let Remove (entryType:EntryType, key) =
  106.         caches |> List.iter (fun c -> c.Remove (entryType.ToString + key ))
  107.    
  108.     let FlushAll =
  109.         caches |> List.iter (fun c -> c.FlushAll)
  110.    
  111.     let FlushAllByType cacheType =
  112.         caches |> List.filter (fun c -> c.GetCacheType = cacheType ) |> List.iter (fun c -> c.FlushAll)
  113.    
  114.     let FlushKeysThatStartWith keyPrefix cacheType =
  115.         caches |> List.filter (fun c -> c.GetCacheType = cacheType ) |> List.iter (fun c -> c.FlushKeysThatStartWith keyPrefix)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement