Question

Below is the code to cache invalid login attempts made by user. Items are being added to cache with 'Absolute Expiration' cache policy.

If I just add one item - it expires as expected in 2 minutes. But if I update that cached item(without explicitly specifying cache policy) - the item remains much longer than 2 minutes. Here is the code snippet:

public class UserLogin
{
    public string Username { get; set; }
    public List<DateTime> InvalidLoginTimestamp { get; set; }
    public bool IsLocked { get; set; }
}    

private void AddInvalidLoginToCache(string cacheKey)
{
    if (invalidLoginCache.Contains(cacheKey))
    {
        //Add invalid login to cache
        UserLogin invalidLogin = (UserLogin)invalidLoginCache[cacheKey];
        invalidLogin.InvalidLoginTimestamp.Add(DateTime.Now);
        invalidLoginCache[cacheKey] = invalidLogin;

        //Lock user account if invalid logins reach threshold
        if (invalidLogin.InvalidLoginTimestamp.Count == 3)
        {
            invalidLogin.IsLocked = true;
            invalidLoginCache.Set(cacheKey, invalidLogin, GetCachePolicyForLockOut());
        }
    }
    else
    {
        invalidLoginCache.Add(cacheKey,
                                new UserLogin { Username = cacheKey, InvalidLoginTimestamp = new List<DateTime> { DateTime.Now } },
                                GetCachePolicyForInvalidLogin());
    }
}

private CacheItemPolicy GetCachePolicyForInvalidLogin()
{
    int keepInvalidLoginFor = 2; //minutes
    CacheItemPolicy cachePolicyForInvalidLogin = new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(keepInvalidLoginFor) };
    return cachePolicyForInvalidLogin;
}

It seems the issue is to do with when I am updating the cache item under //Add invalid login to cache

Any ideas on what I am missing here and how can I fix this issue?

Was it helpful?

Solution

ILSpy reveals that:

invalidLoginCache[cacheKey] = invalidLogin;

is equivalent to:

invalidLoginCache.Set(
    cacheKey, invalidLogin, 
    ObjectCache.InfiniteAbsoluteExpiration, null);

Does this explain what you're seeing?

Why don't you call Set, passing an explicit policy?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top