C
C#13mo ago
ZimmertyZim

Cache not clearing, what am I missing?

Does anyone know why this cache is not clearing? I am trying to implement simple rate limiting an and old MVC application. If a POST endpoint is hit too many times, return a 500/429. My approach:
private bool IsAllowed(string controllerName, string actionName, string ipAddress)
{
var isAllowed = true;
var maxRequests = 3;
var timeframeMins = 3;
var cacheKey = $"{controllerName}-{actionName}-{ipAddress}";

MemoryCache cache = MemoryCache.Default;
CacheItemPolicy policy = new CacheItemPolicy
{
AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(timeframeMins),
Priority = System.Runtime.Caching.CacheItemPriority.Default,
};

if (cache.Get(cacheKey) == null)
{
cache.Add(cacheKey, 1, policy);
}
else
{
var hitCount = (int)cache.Get(cacheKey);
hitCount++;
cache[cacheKey] = hitCount;

if (hitCount > maxRequests)
{
isAllowed = false;
}
}

return isAllowed;
}
private bool IsAllowed(string controllerName, string actionName, string ipAddress)
{
var isAllowed = true;
var maxRequests = 3;
var timeframeMins = 3;
var cacheKey = $"{controllerName}-{actionName}-{ipAddress}";

MemoryCache cache = MemoryCache.Default;
CacheItemPolicy policy = new CacheItemPolicy
{
AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(timeframeMins),
Priority = System.Runtime.Caching.CacheItemPriority.Default,
};

if (cache.Get(cacheKey) == null)
{
cache.Add(cacheKey, 1, policy);
}
else
{
var hitCount = (int)cache.Get(cacheKey);
hitCount++;
cache[cacheKey] = hitCount;

if (hitCount > maxRequests)
{
isAllowed = false;
}
}

return isAllowed;
}
This cache item never expires. The same thing happens if I am using the HttpContext cache approach: ...
HttpContext.Current.Cache.Insert(cacheKey,
1,
null,
DateTimeOffset.UtcNow.AddMinutes(timeframeMins),
Cache.NoSlidingExpiration,
CacheItemPriority.Low)

...

HttpContext.Current.Cache[cacheKey] = hitCount;
HttpContext.Current.Cache.Insert(cacheKey,
1,
null,
DateTimeOffset.UtcNow.AddMinutes(timeframeMins),
Cache.NoSlidingExpiration,
CacheItemPriority.Low)

...

HttpContext.Current.Cache[cacheKey] = hitCount;
etc. Any idea? I am testing this by running an external script that hits the end point multiple times. I can trigger the rejection, but the cache never clears, so the limiting/blocking always remains in place.
1 Reply
ZimmertyZim
ZimmertyZimOP13mo ago
Still not sure what's going on here. I0 am guessing the cache resets or adds time somehow every time I update the hitCount, it is my understanding that shouldn't be the case. I've just created a second cache item and that tracks the same expiry time. This one clears as expected, so if it's empty I can reset the original cache item (doesn't matter if has become null at that point as a new one is just created):
Want results from more Discord servers?
Add your server