Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a good way to implement cache aside pattern?

For example, I have some repositories to grab some data I need:

Addressrepository.GetAddress(string para1, string para2)

UserRepository.GetUserDetail(string userName)

FinancialRepository.GetFinancialInfo(int userId)

To apply a cache aside pattern, I would like to do this:

  1. base on parameters passing in and some identifier for each repository, construct a key.
  2. Check Memory cache(or redis cache if we do down that route).
  3. If info can't be found or expired, call the repository function to grab data and put into cache.

Ideally I would like to write a generic helper class to do this for all data loading functions.Something like the cache aside pattern described here: https://blog.cdemi.io/design-patterns-cache-aside-pattern/

However, in my case, I need to pass different parameters to different methods. In this case, is it possible to use Func and pass different parameters?

I checked msdn about this:

Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> Delegate

But how do I pass different type parameter and different number of parameters?

like image 202
daxu Avatar asked Jun 12 '17 16:06

daxu


People also ask

What is the cache Aside pattern?

Cache-Aside (Lazy Loading) If the data is available (a cache hit), the cached data is returned, and the response is issued to the caller. If the data isn't available (a cache miss), the database is queried for the data.

How do you implement caching?

So the standard way to implement cache is to have a data structure, using which we can access value by a given key in constant time. Now all good, we can save key value pairs in memory and retrieve it whenever we need it.

How would you implement caching in Microservices?

Cache Storage Location Distributed caching can use either of these two approaches: Private caching and Shared Caching. Private Caching is fast, and the data resides in the memory of a service instance. If your microservices-based application has several instances, each instance would have its own copy of cached data.


1 Answers

The easiest way is by not passing the parameters in at all and instead doing variable capture.

public T GetOrAdd<T>(string key, Func<T> builder)
{
    var result = _someCache.Get<T>(key);
    if(result != null)
       return result;

    result = builder();
    _someCache.Add(key, result);
    return result;
}

used like

var address = myCache.GetOrAdd<Address>(AddressKeyBuilder(para1, para2), 
                                        () => Addressrepository.GetAddress(para1, para2)
                                       );

This is the same pattern ConcurrentDictionary uses for it's GetOrAdd method.

like image 114
Scott Chamberlain Avatar answered Sep 28 '22 19:09

Scott Chamberlain