[CSHARP-2131] Concurrency for BsonClassMap registration Created: 19/Dec/17  Updated: 27/Oct/23  Resolved: 23/Jan/18

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: James Turner Assignee: Robert Stam
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently the implementation of BsonClassMap stores the type/map against a regular Dictionary. Under most circumstances (and as the documentation briefly touches on), this isn't a problem as you can map classes at the beginning of the program however in some cases, you can only map the class just-in-time.

Is it possible to switch from a regular Dictionary and instead to the ConcurrentDictionary? As far as I can tell, it should be a fairly simple drop-in replacement with really only two lines changed (besides the additional "using" directive):

    public class BsonClassMap
    {
        // private static fields
        private readonly static ConcurrentDictionary<Type, BsonClassMap> __classMaps = new ConcurrentDictionary<Type, BsonClassMap>();
        ...

        public static void RegisterClassMap(BsonClassMap classMap)
        {
            if (classMap == null)
            {
                throw new ArgumentNullException("classMap");
            }
 
            BsonSerializer.ConfigLock.EnterWriteLock();
            try
            {
                // note: class maps can NOT be replaced (because derived classes refer to existing instance)
                __classMaps.TryAdd(classMap.ClassType, classMap);
                BsonSerializer.RegisterDiscriminator(classMap.ClassType, classMap.Discriminator);
            }
            finally
            {
                BsonSerializer.ConfigLock.ExitWriteLock();
            }
        }

Based on the comment in the code, I think a TryAdd is our only option as an AddOrUpdate will likely cause issues.

I've marked this as an improvement more than a bug as under most use cases, it isn't an issue.



 Comments   
Comment by Robert Stam [ 23/Jan/18 ]

Closed at the original submitters request.

Comment by James Turner [ 06/Jan/18 ]

Thinking about this more, I'm actually not sure anymore if a change to a concurrent dictionary is the best idea.

My problem isn't that the driver has a direct problem with two (or more) threads adding class maps, it is how the locking is performed in relation to my own code. I do my own checks to see if the class map exists and register one if it doesn't but because the locking is performed to inside the `RegisterClassMap` as opposed to inside my method, the issue occurs.

Though I'm really only in this position because `LookupClassMap` freezes the classmap. If it didn't, then my code could depend on the locking that driver does internally anyway.

You can close this issue as I will implement locking for my code that wraps the driver.

Generated at Wed Feb 07 21:41:41 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.