Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mediatr - Where is the right place to invalidate/update cache

This question stems from this other question I had asked about too many interfaces, QCRS and Mediatr library (request/response)

Mediatr: reducing number of DI'ed objects

I have created bunch of commands and queries and I have bunch of behaviors and one of them being is a Cache behaviour that for every query, cache is checked for the value before the query is actually executed against the db. So far this is working great, but the delima comes in when I have an UpdateSomethingCommand, once I update the underlying object in the db, I would like to refresh the cache with what was successfully saved to the db.

My question is specifically when to actually update the cache:

  1. In the UpdateSomethingCommandHandler (this might be breaking the SOLID principal)
  2. Call another command in UpdateSomethingCommandHanlder that is specifically designed to update caches (not sure this is a good design principal)
  3. Introduce another behavior that is specifically designed for updating caches (not sure how to go about this yet)
  4. Is there a better solution?
like image 513
Zoinky Avatar asked Dec 30 '18 20:12

Zoinky


People also ask

When should you invalidate cache?

extra is associated with the CSV file, cache will be invalidated when the file is changed (because the cache key will be different). Another example is one code chunk using a variable created from a previous code chunk. When the variable is updated in the previous chunk, this chunk's cache should be invalidated, too.

What is MediatR .NET core?

MediatR Requests are very simple request-response style messages, where a single request is synchronously handled by a single handler (synchronous from the request point of view, not C# internal async/await). Good use cases here would be returning something from a database or updating a database.


1 Answers

We had a similar need on a project that uses MediatR and ended up incorporating caching into the mediator pipeline, including cache invalidation as you describe.

The basic premise is that we have two different behaviors inserted into the pipeline, one for caching a response from a request, and one for invalidating a cached request response from a different request.

There is a little bit of interplay between the two behaviors in the fact that they need to exchange a cache key in order to invalidate the correct request.

I've recently pulled some of this work into a stand-alone library that in theory can be dropped in as-is to any project using MediatR. In your case, you may just want to look at the techniques we've used here and recreate them as needed.

Rather than repeat everything here and now, I'll point you at the project page where there is some documentation under the Getting Started link on the homepage: https://github.com/Imprise/Imprise.MediatR.Extensions.Caching

In my opinion, the cache invalidation makes the whole process extremely simple and straightforward, but there are cases where we needed finer control over when the invalidation occurs. In these cases the other approach we have taken is to inject an ICache<TRequest, TResponse> cache into INotificationHandlers and then call _cache.Remove(key); manually as needed. Then, from any requests you know should invalidate just raise a notification that is handled by the INotificationHandler e.g. _mediator.Publish(SomethingUpdated);

like image 169
djjlewis Avatar answered Oct 08 '22 13:10

djjlewis