Hi I am looking for some patterns or other advice on building a transparent “CRUD cache” with redis, or said another way, a relational or no-sql backed redis cache. It would need to support both single objects as well as data sets (time series of metrics)
The easiest way is to use the CacheResponse Attribute to configure caching for your Services based on how long you want to be able to cache for. If you register Redis as your ICacheClient the cache is automatically saved in Redis based on the relative url and modifiers for each request.
But if you want to cache by key, there’s no real magic bullet - you need to come up with a cache key naming strategy that you can save your Web Services response under that you also need to be able to clear. TechStacks originally used this approach where we had a central ContentCache
class that had all the cache keys our Services used but we’ve since converted it to use the much less invasive [CacheResponse]
attribute in this commit which shows the differences between the old and new caching strategy. If you’re going to go with the individual cache key approach then you’re going to find it tough to know which Data Sets to invalidate when an individual item changes, in these cases we basically invalidated all data sets.
But if it’s possible I’d recommend going with time-based caching that way caches are periodically invalidated which requires significantly less effort to maintain.
So was looking for something perhaps underneath the service layer. So for example, if we have a set of data for a user, say recent purchases, we want to hook an authorization call and pre-cache that data for them, but the service to get the data has not been called yet. When the getRecentPurchases service is called, we’d want to basically have it call the CRUD layer, and the CRUD layer be able to read and write through cache. I realize this isn’t servicestack specific.
I’ve done this pattern just using dictionaries but its not distributed, hence the question about redis.
As far as invalidating… we avoid that problem by not having joins (basically, if you want children, go get them yourself). The time based tip is a good one, thanks, – although I don’t think we would normally be operating without cache pressure anyway.