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

CacheManager core with couchdb throws error while trying to get an exsiting cache item #297

Open
abdou89 opened this issue Jan 10, 2020 · 4 comments
Milestone

Comments

@abdou89
Copy link

abdou89 commented Jan 10, 2020

Hello,
I'm using Cachemanager core (v 1.2.0 ) with the following config


var definition = new CouchbaseClientDefinition();
            configuration.GetSection("CoucheDb").Bind(definition);
            var clientConfig = new ClientConfiguration(definition);
            ICacheManager<string> CacheInstance = CacheFactory.Build<string>(settings =>
            {
                settings
                 //Memory cach 
                 //.WithMicrosoftMemoryCacheHandle(). WithExpiration(ExpirationMode.Sliding, TimeSpan.FromMinutes(60)) 
                 // .And
                 //couch  cach 
                .WithCouchbaseConfiguration("couchedb", clientConfig)
                 .WithJsonSerializer()
                .WithMaxRetries(5)
                 .WithRetryTimeout(100)   
                 .WithCouchbaseCacheHandle("couchedb"); 


            });
             
                serviceCollection.AddSingleton(CacheInstance);

In my code below ,I use the cache instance to check for a key , if it doesn't exist it's then added to the cache , the _cache.Exists() and _cache.add() are working fine and the the item is added also in the couche db as a json doc (see joined file ) , but the Get function throws a nullReferenceException and I fail to figure out why.

Code snippet :

  if ( _cacheManager.Exists("item_key")  )
       {
        var cachedItem = _cacheManager.Get("item_key"); 
       }
     else                  
       {
   _cacheManager.Add("item_key", "item_value");
       }

Exception :
{System.NullReferenceException: Object reference not set to an instance of an object. at CacheManager.Core.Internal.BaseCache1.Get(String key)`

couch data :

snip_couch

Thanks in advance

@shamork
Copy link

shamork commented Apr 26, 2020

net4.6.1 is ok, net core not working ?
i have the same problem.

@shamork
Copy link

shamork commented Apr 27, 2020

After two days digging, found code bellow in NewtonSoft.Json.
case JsonContractType.Serializable: this.SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract, member, containerContract, containerProperty); return;

If an object is Serializable, it will serialize it use ISerializable interface.
CacheItem implemets ISerializable in net452, but not in netstandard2.
Default JsonSerializerSettings in Couchbase.Core.Serialization.DefaultTranscoder which has set CamelCasePropertyNamesContractResolver is ignored. This cause netstandard version generates "key" as net452 version genterates "Key".

Another problem is: there isn't a ctor take a serializer param in CacheManager.Couchbase. So the serializer setting is ignored.

@shamork
Copy link

shamork commented Apr 27, 2020

there is two workaroud for this:

  1. Implemets ISerializable in netstandard2. This is a breaking change for netstand2 users!
  2. Catch the expcetion, and reset the cached data, old data will be lost! (recommended)

this problem can only happen after you stored data use one version(net452/netstandard2) and try to get/update data use another version

@MichaCo
Copy link
Owner

MichaCo commented Apr 27, 2020

Uh oh OK.
Thanks for digging into this and figuring it out man! That's pretty unfortunate.

I actually didn't know that Newtonsoft.Json handles the serializable interface/attribute like this. I knew it respects the properties added to the SerializationInfo.

The fact that it doesn't handle casing properly sounds more like a bug though.

CacheItem has that kind of implementation because the .Core package supports binary serialization in the full framework target. That path is not supported in netstandard because some types like Type are not binary serializable anymore in .NET Core.

Regarding the workarounds, I agree with you. And I also don't have a better solution.
I will most likely remove the binary serialization all together in a future version though which will also get rid of the Serializable attribute / interface implementation.

@MichaCo MichaCo added this to the Future milestone Apr 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants