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

Concurrency Issue #29

Open
arjun-khadka-beyondid opened this issue Aug 10, 2020 · 8 comments
Open

Concurrency Issue #29

arjun-khadka-beyondid opened this issue Aug 10, 2020 · 8 comments
Labels
bug Something isn't working

Comments

@arjun-khadka-beyondid
Copy link

arjun-khadka-beyondid commented Aug 10, 2020

Code USed: Startup.cs

       DeviceDetector.SetVersionTruncation(VersionTruncation.VERSION_TRUNCATION_NONE); 

       var userAgent = context.Request.Headers["User-Agent"]; 

        var deviceDetector = new DeviceDetector(userAgent); 

        deviceDetector.Parse(); 

Issue encounter:
System.InvalidOperationException: Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.

at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)

at System.Collections.Generic.Dictionary`2.ContainsKey(TKey key)

at DeviceDetectorNET.Cache.DictionaryCache.Contains(String id)

at DeviceDetectorNET.Cache.DictionaryCache.Fetch(String id)

at DeviceDetectorNET.Parser.ParserAbstract`2.GetRegexes()

at DeviceDetectorNET.Parser.Client.LibraryParser..ctor()

at DeviceDetectorNET.Parser.Client.ClientType.get_Library()

at DeviceDetectorNET.DeviceDetector.AddClientsParser()

at DeviceDetectorNET.DeviceDetector..ctor(String userAgent)

@totpero totpero added the bug Something isn't working label Sep 7, 2020
@cpkuo
Copy link

cpkuo commented Jun 9, 2022

I'm getting the same issue, somewhat random. Aside from restarting the process, how can I avoid getting this error? Once its in a corrupt state, it seems only a restart can solve it.

@schneidenbach
Copy link

Same thing, this bug suddenly appeared today.

@cpkuo
Copy link

cpkuo commented Jun 16, 2022

In the meantime I've just implemented a cache check with concurrent dictionary before making a call to DeviceDetectorNET

@schneidenbach
Copy link

@cpkuo care to share the code? :)

@cpkuo
Copy link

cpkuo commented Jun 21, 2022

Sure, there is still the possibility that DeviceDetector will write to it's internal cache collection on concurrent requests but this seems to have helped me in a high load environment. I wonder if setting a new instance of DictonaryCache on each request in combination with the custom ConcurrentDictionary cache will completely eliminate the error. I will need to review the source code at some point, in the meantime here is some code.

`private static ConcurrentDictionary<string, DeviceInfo> cache = new ConcurrentDictionary<string, DeviceInfo>();
private static DictionaryCache dicationaryCache = new DictionaryCache();

public DeviceInfo Get(string userAgent)
{
    if (cache.ContainsKey(userAgent))
    {
        return cache[userAgent];
    }

    //Domain class
    var info = new DeviceInfo();

    DeviceDetector.SetVersionTruncation(VersionTruncation.VERSION_TRUNCATION_NONE);
    var dd = new DeviceDetector(userAgent);

    dd.SetCache(dicationaryCache);
    dd.Parse();

    var client = dd.GetClient();

    //Transfer result into domain class DeviceInfo
    //  .......

    cache.TryAdd(userAgent, info);

    return info;
}`

@cpkuo
Copy link

cpkuo commented Jul 12, 2022

So I went into the source code to match up with the stack trace for this exception and realized I was using a dotnet core version package of DeviceDetector.NET that I don't believe exists anymore. Nuget package manager was not notifying me of updating. So I removed it and started using the latest package of DeviceDetector.NET which now supports the latest .net standard. So far, I have not run into this issue.

@totpero totpero closed this as completed Jun 7, 2023
@adamhathcock
Copy link

This can still happen:

System.InvalidOperationException: Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.
  at System.Collections.Generic.Dictionary`2.FindValue(TKey key)
  at System.Collections.Generic.Dictionary`2.ContainsKey(TKey key)
  at DeviceDetectorNET.Cache.DictionaryCache.Contains(String id)
  at DeviceDetectorNET.Cache.DictionaryCache.Fetch(String id)
  at DeviceDetectorNET.Parser.ParserAbstract`2.GetRegexes()
  at DeviceDetectorNET.Parser.Client.MediaPlayerParser..ctor()
  at DeviceDetectorNET.Parser.Client.ClientType.get_MediaPlayer()
  at DeviceDetectorNET.DeviceDetector.AddClientsParser()
  at DeviceDetectorNET.DeviceDetector..ctor(String userAgent)
  at

I'm now following the advice to cache userAgents and I set SetVersionTruncation once statically

@totpero totpero reopened this Nov 8, 2023
@adamhathcock
Copy link

I did my final fix has having a custom ICache with ConcurrentDictionary instead of just Dictionary

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants
@adamhathcock @totpero @schneidenbach @cpkuo @arjun-khadka-beyondid and others