Reputation: 17939
So I have a cache system for a single value with a type like this:
module CachedSessionToken =
// returns a lazy value that initializes the cache when
// accessed for the first time (safely)
let private createCacheInitialization() =
lazy(SomeLongRunningOperationThatReturnsAString())
// current cache represented as lazy value
let mutable private currentCache = createCacheInitialization()
// Reset - cache will be re-initialized next time it is accessed
// (this doesn't actually initialize a cache - just creates a lazy value)
let Reset() = currentCache <- createCacheInitialization()
let GetCache() =
currentCache.Value
And this works.
However, when I try to do the same for something else (a sequence of objects), it seems that the value is never retained, it's all the time evaluated every time I request it, why? The code below:
module CachedLayout =
let mutable private lastAccess:Option<DateTime> = None
// returns a lazy value that initializes the cache when
// accessed for the first time (safely)
let private createCacheInitialization() =
lazy(
seq {
yield new SomeObject (".")
yield new SomeObject ("..")
let folderPaths = SomeLongRunningOperationThatReturnsArrayOfStrings()
lastAccess <- Option.Some(DateTime.Now)
for name in folderPaths
do yield new SomeObject (name)
let filePaths = SomeOtherLongRunningOperationThatReturnsArrayOfStrings()
lastAccess <- Option.Some(DateTime.Now)
for name in filePaths
do yield new SomeObject (name)
}
)
// current cache represented as lazy value
let mutable private currentCache = createCacheInitialization()
// Reset - cache will be re-initialized next time it is accessed
// (this doesn't actually initialize a cache - just creates a lazy value)
let Reset() = currentCache <- createCacheInitialization()
let GetCache() =
if (lastAccess.IsSome && DateTime.Now > (lastAccess.Value + TimeSpan.FromSeconds (10.0))) then
Reset()
currentCache.Value
Upvotes: 0
Views: 73
Reputation: 17939
Ok, I just realised why: the type that the lazy() thingy returns. If it's a sequence, it will be always evaluated because it's not a proper object that can be stored.
I had to change it to this to make it work:
// returns a lazy value that initializes the cache when
// accessed for the first time (safely)
let private createCacheInitialization() =
lazy(
new List<SomeObject>(seq {
yield new SomeObject (".")
yield new SomeObject ("..")
let folderPaths = SomeLongRunningOperationThatReturnsArrayOfStrings()
lastAccess <- Option.Some(DateTime.Now)
for name in folderPaths
do yield new SomeObject (name)
let filePaths = SomeOtherLongRunningOperationThatReturnsArrayOfStrings()
lastAccess <- Option.Some(DateTime.Now)
for name in filePaths
do yield new SomeObject (name)
})
)
Upvotes: 1