Skip to content

Repository files navigation

RedisMemoryCacheInvalidation - Core

A migration and changes to RedisMemoryCacheInvalidation as PRs were going stale and the package appears abandoned.

NugetNuget

System.Runtime.MemoryCache invalidation using Redis PubSub feature.

Installing via NuGet

Install-Package RedisMemoryCacheInvalidationCore

How to use it ?

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.csInvalidationManager.Configure("localhost:6379",newInvalidationSettings());

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 monitor InvalidationManager.CreateChangeMonitor
  • InvalidationStrategyType.AutoCacheRemoval => use the automatic MemoryCache removal configured at InvalidationSettings.ConfigureAsync
  • InvalidationStrategyType.External => use the callback configured at InvalidationSettings.InvalidationCallback

How it works ?

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

Configuration

Settings

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 InvalidationStrategy is set to AutoCacheRemoval.
  • EnableKeySpaceNotifications:bool : allow subscribe to keyevents notification __keyevent*__:.
  • InvalidationCallback:Action : a callback that is invoked when InvalidationStrategy is set to External.

Configuring Redis

# 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 in

When to configure ?

Thanks 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.

Examples

Once RedisMemoryCacheInvalidation is configured, local cache invalidation is a two-steps process : capturing invalidation messages and handling those notification messages.

Sending invalidation 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)

Handling notification messages

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)
varsettings=newInvalidationSettings{EnableResilience=true,HealthCheckIntervalMs=15000,// 15 secondsMaxRetryAttempts=5,RetryDelayMs=500};InvalidationManager.Configure("localhost:6379",settings);

License

Licensed under the terms of the MIT License

About

RedisMemoryCacheInvalidationCore

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages