A migration and changes to RedisMemoryCacheInvalidation as PRs were going stale and the package appears abandoned.
System.Runtime.MemoryCache invalidation using Redis PubSub feature.
Install-Package RedisMemoryCacheInvalidationCore
quick start
First, you have to configure the library, mainly to set up a persistent redis connection and various stuff
// somewhere in your global.asax/startup.cs
InvalidationManager.Configure("localhost:6379", new InvalidationSettings());Redis connection string follow StackExchange.Redis Configuration model
There are at least 3 ways to send invalidation messages :
- send an invalidation message via any redis client following the command
PUBLISH invalidate onemessagekey - use
InvalidationManager.InvalidateAsync(same as the previous one) - use keyspace notification (yes, RedisMemoryCacheInvalidation supports it)
Once an invalidation message is intercepted by the library, you can invalidate one or more items at the same time by
using InvalidationSettings.InvalidationStrategy
InvalidationStrategyType.ChangeMonitor=> a custom change monitorInvalidationManager.CreateChangeMonitorInvalidationStrategyType.AutoCacheRemoval=> use the automatic MemoryCache removal configured atInvalidationSettings.ConfigureAsyncInvalidationStrategyType.External=> use the callback configured atInvalidationSettings.InvalidationCallback
A single connection is opened to redis via the servicestack thread-safe multiplexer.
The library uses a topic-based observer pattern to manage notifications within the application; allowing for a large number of possible monitors.
Invalidation messages are sent in the format channel=invalidate and message=key-to-invalidate.
As the name suggests, this implementation relies on Redis, especially on PubSub feature. In the current version of this implementation, nothing is stored on the Redis server.
+------------------------------------------+
| System.Runtime.Caching.MemoryCache |
| clients (Frontend/Backend Servers) |
|------------------------------------------|
| [Server1] [Server2] [Server3] |
+------------------------------------------+
^ ^ ^ |
| | | |
| | | v
| | | 5 - Remove items from local cache
| | +---------------------------+
| | |
| +--------------------------------+
| |
| |
| 2 - OnDemand: Load data |
| from Data Tier |
| |
+-------------------+ |
| Data Tier |<----------------------+
+-------------------+
^
| 4 - Send notification
|
+-------------------+
| Redis |
| (Invalidations) |
+-------------------+
^ |
1 - Subscribe | | 3 - Publish Invalidation
on startup | | (when something changed)
| v
| +-------------------+
| | Publisher |
| +-------------------+
|
3' - Publish Invalidation
from any redis client
To configure RedisMemoryCacheInvalidation, you should use one of the InvalidationManager.ConfigureAsync methods.
Three parameters are available to configure it :
- redisConfig:string : Redis connection string. Check StackExchange.Redis Configuration model for more details. A basic example is
localhost:6379. - mux:ConnectionMultiplexer : an existing StackExchange.Redis.ConnectionMultiplexer that you want to reuse.
- settings:InvalidationSettings : see below for more details.
InvalidationSettings is the main configuration object
- InvalidationStrategy:InvalidationStrategyType : How to handle invalidation notifications : notify ChangeMonitor, execute callback or automatically remove an item from the cache.
- TargetCache:MemoryCache : the target MemoryCache instance when
InvalidationStrategyis set toAutoCacheRemoval. - EnableKeySpaceNotifications:bool : allow subscribe to keyevents notification
__keyevent*__:. - InvalidationCallback:Action : a callback that is invoked when
InvalidationStrategyis set toExternal.
# Enable keyevent notifications for all event types
CONFIG SET notify-keyspace-events KEA
# Quick test
# Terminal 1: Subscribe to all keyevent notifications
redis-cli PSUBSCRIBE '__keyevent*__:*'
# Terminal 2: Trigger an event
redis-cli SET foo bar
redis-cli DEL foo
# You should see the events stream inThanks to StackExchange.Redis a persistent connection is established between your application and the redis server. That's why it's important to configure it very early at startup : Global.asax, Owin or Application Initialisation.
Once RedisMemoryCacheInvalidation is configured, local cache invalidation is a two-steps process : capturing invalidation messages and handling those notification messages.
You can use one of the folowing methods.
- Send a pubsub message from any redis client
PUBLISH invalidate onemessagekey. - Send an invalidation message from
InvalidationManager.InvalidateAsync("onemessagekey") - Capture keyspace events for one particular key. Note : the redis server should be configured to support keyspace events. (off by default)
This behavior is entirely configured via InvalidationSettings.InvalidationStrategyType. As it's marked with a FlagsAttribute, you can use one or more strategies.
- Automatically removed a cache item from the cache
The easiest way to invalidate local cache items. If the The core will try to remove cache items For example, if you add a cache item like this :
CacheItem cacheItem = new CacheItem("mycacheKey", "cachevalue");
CacheItemPolicy policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTime.UtcNow.AddDays(1);
MyCache.Add(cacheItem, policy);
Calling PUBLISH invalidate mycacheKey or InvalidationManager.InvalidateAsync("mycacheKey") will remove that item from the cache.
- Notify ChangeMonitors
ChangeMonitor is defined as "Provides a base class for a derived custom type that monitors changes in the state of the data which a cache item depends on.""
You can create a custom monitor (watching for myinvalidationKey) like this :
CacheItem cacheItem = new CacheItem("cacheKey", "cachevalue");
CacheItemPolicy policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTime.UtcNow.AddDays(1);
policy.ChangeMonitors.Add(InvalidationManager.CreateChangeMonitor("myinvalidationKey"));
MyCache.Add(cacheItem, policy);
When raised the corresponding cache item will be automatically removed. One interesting feature is that you can create several change monitors watching for the same key.
- invoke a callback
Suppose you're using another caching implementation there is another way to be notified with InvalidationStrategyType.External.
Each time a notification message is intercepted, the callback defined in InvalidationSettings.InvalidationCallback is invoked.
It's up to you to remove/flush/reload the cache item.
- Enabling resilience (retrys)
var settings = new InvalidationSettings
{
EnableResilience = true,
HealthCheckIntervalMs = 15000, // 15 seconds
MaxRetryAttempts = 5,
RetryDelayMs = 500
};
InvalidationManager.Configure("localhost:6379", settings);Licensed under the terms of the MIT License