Is DefaultCacheManager thread-safe?

Topics: Core, Writing modules
Dec 25, 2011 at 6:10 PM

It looks it is (this issue is only vaguely related despite its title), but just to make sure: am I correctly assuming that if more than one threads make concurrent calls to the CacheManager's Get() with the same cache key then subsequent calls (after the first one hits the CacheManager) get a cached result? That means if there are two or more calls at the same time to Get() with the same cache key, the Func fed to Get() will only be executed once?

Recently there was a discussion about the underlying cache mechanism and that it may change. Will this affect thread-safety?

Thanks in advance.

Jan 6, 2012 at 4:55 AM

I'm not sure I understand why it would need to be thread-safe. If two threads were asking for the same resource at the same time, well, the Lambda would be called by both. So what?

Jan 6, 2012 at 8:33 AM

My hope was almost gone that someone will answer, thanks :-).

Then I guess the cache key is allocated at the time the lambda returns?

To illustrate why I'm asking this (forgive the pseudocode):

HeavyMethod(string param)
    var result = CacheManager.Get(key1) // Note that this is cached independently from param
        some heavy processing

    var finalResult = CacheManager.Get(param) // Note that the cache key depends on param
        some heavy processing that needs result

Now there are two possibilities:

  1. HeavyMethod() gets called by two (or more...) concurrent background threads, with different params, spawned off from e.g. a controller action. (The caller knows nothing about the caching, so is happy to do this.) Both of the calls first need to compute result, and I'd like to happen it only once.
  2. Two page requests happen at the same time (with different or even with the same param), so there are two calls to HeavyMethod() concurrently. Again, I'd like result (and finalResult) to be computed only once.

To achieve that result is only computed once and subsequent calls use the cached result I guess there should be a static locker object?

I'm still learning about ASP.NET too so my mental model of what's happening might be inaccurate, thus I could misunderstood the workflow...

Jan 6, 2012 at 3:56 PM

The outcome where the cache value is computed twice will be extremely rare. Thread safety is another way of saying no deadlocks or consistency failures because of concurrent access (but that is not the case here as far as I can tell). The argument you seem to be making is one of performance, not thread safety. So we're talking about making a method considerably more complex in order to optimize performance in an extremely rare case. That doesn't seem like a reasonable thing to do.

Jan 6, 2012 at 4:40 PM

Yes, you're right, I misused the term.

If we're looking at the first scenario, where multiple threads are started, the side-by-side processing of the same result for a cache entry would happen on all yet uncached requests, so it wouldn't be so rare, although nevertheless only the first hit would be penalized.