Reputation: 1378
Currently I'm teaching myself some F# and do so working on an (dumb) application that reads and updates customers that are stored in a database. Each customer has a property 'customer type', which is stored in a separate table in the database. Since the list of customer types is practically constant, I want to cache the database query that fetches these customer types, e.g.
let getCustomerTypes =
let allTypes = SomeDbFunction |> Seq.map SomeMappingFunction
Seq.cache allTypes
Now I've stubled upon the problem that when I insert a new customer type (again, this happens say once a month), a call to getCustomerTypes doesn't reflect the newly inserted customer type. To solve this problem, I've looked at memoization, e.g. http://blogs.msdn.com/b/dsyme/archive/2007/05/31/a-sample-of-the-memoization-pattern-in-f.aspx. However, the intent of memoization is to return a value if it has previously been calculated, but that doesn't fit my scenario.
What is the recommened functional / F# way to update a cache?
Upvotes: 0
Views: 202
Reputation: 14328
[Promoting comment to an answer]
I'd use MemoryCache to avoid recreating cache eviction rules, but also for safety and peace of mind.
If you're after the simplest in-memory, key-value cache, then IDictionary<TKey,TValue>
is the obvious available option.
Also, watch out for race conditions when using a dictionary. :)
Upvotes: 2
Reputation: 5688
As written, getCustomerTypes
is not a function. It is a value which is computed only once. To force re-computation on each reference, make it a function:
let getCustomerTypes () =
let allTypes = SomeDbFunction |> Seq.map SomeMappingFunction
Seq.cache allTypes
I'm not sure what you mean by "cache the database query"—it seems to me you'd have to actually perform the query in order to know whether you have any new customers, which would seem to defeat the purpose of caching.
Upvotes: 0