Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DictionaryHandle - sporadic NullReferenceException #167

Closed
burnstek opened this issue Jun 14, 2017 · 3 comments
Closed

DictionaryHandle - sporadic NullReferenceException #167

burnstek opened this issue Jun 14, 2017 · 3 comments
Assignees
Labels
Milestone

Comments

@burnstek
Copy link

burnstek commented Jun 14, 2017

Hello! Rarely, we see this occur. I don't know the steps to repro, but it does happen from time to time. We can't repro with MemoryCacheHandle.

06/14 15:42:40 - System.NullReferenceException: Object reference not set to an instance of an object.
   at CacheManager.Core.Internal.DictionaryCacheHandle`1.GetCacheItemInternal(String key, String region)
   at CacheManager.Core.Internal.DictionaryCacheHandle`1.GetCacheItemInternal(String key)
   at CacheManager.Core.Internal.BaseCache`1.GetCacheItem(String key)
   at CacheManager.Core.BaseCacheManager`1.GetCacheItemInternal(String key, String region)
   at CacheManager.Core.BaseCacheManager`1.GetCacheItemInternal(String key)
   at CacheManager.Core.Internal.BaseCache`1.GetCacheItem(String key)
   at CacheManager.Core.Internal.BaseCache`1.Get(String key)
   at CacheManager.Core.Internal.BaseCache`1.Get[TOut](String key)
   at DataCache.DataCacheClient.Get[T]() in 

Looking at DictionaryCacheHandle.cs, I have no idea what could be going wrong. Apparently _cache is null on this line, but it's not clear at all how that could be.

if (_cache.TryGetValue(fullKey, out CacheItem<TCacheValue> result))

Here is a sample config I use to reproduce this:

_cache = CacheFactory.Build(s => s
                .WithJsonSerializer()
                .WithDictionaryHandle()
                .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromSeconds(60)) 
                .And
                .WithRedisConfiguration("redis", multiplexer, 1)
                .WithRedisCacheHandle("redis")
                .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromSeconds(180))); 

And the test harness:

                        for (int j = 0; j < 100; j++) // test this N times.
                        {
                            new Thread(() =>
                            {
                                _cache.Get("some_key");
                            }).Start();
                        }
@MichaCo
Copy link
Owner

MichaCo commented Jun 14, 2017

I cannot reproduce the error at all. Running it on Windows 10 Fullframework and netstandard not on Linux.

@MichaCo
Copy link
Owner

MichaCo commented Jun 15, 2017

Ok turns out I already fixed that part in a more recent check-in...

There was a potential race condition issue in line 127 where result can be null if the TryRemove returns false. That was a bug.

Will be fixed in the next patch release... sorry ;)

here is a more reliable way to reproduce it

   var _cache = CacheFactory.Build(s => s
        .WithDictionaryHandle()
        .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromMilliseconds(10))
        .And
        .WithDictionaryHandle()
        .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromMilliseconds(20))
        .And
        .WithDictionaryHandle()
        .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromMilliseconds(30))
        .And
        .WithDictionaryHandle()
        .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromMilliseconds(40))
        .And
        .WithDictionaryHandle()
        .WithExpiration(ExpirationMode.Absolute, TimeSpan.FromMilliseconds(50))
        );

    _cache.OnRemoveByHandle += (s, a) =>
    {
        Console.Write(a.Level);
    };

    while (true)
    {
        Action act = () =>
        {
            try
            {
                var val = _cache.Get("some_key");
                if (val == null)
                {
                    _cache.Put("some_key", "value");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        };

        Parallel.Invoke(Enumerable.Repeat(act, 1000).ToArray());
    }

@MichaCo MichaCo added the bug label Jun 15, 2017
@MichaCo MichaCo self-assigned this Jun 15, 2017
@MichaCo MichaCo added this to the 1.1.1 milestone Jun 15, 2017
@MichaCo
Copy link
Owner

MichaCo commented Jul 2, 2017

fixed in 1.1.1

@MichaCo MichaCo closed this as completed Jul 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants