Skip to content

Conversation

jbogard
Copy link
Contributor

@jbogard jbogard commented Nov 15, 2017

Fixes #2394

@jbogard jbogard added the Bug label Nov 15, 2017
private static readonly SourceMember[] Empty = new SourceMember[0];
private readonly Dictionary<TypeDetails, SourceMember[]> _allSourceMembers = new Dictionary<TypeDetails, SourceMember[]>();
private LockingConcurrentDictionary<TypeDetails, SourceMember[]> _allSourceMembers
= new LockingConcurrentDictionary<TypeDetails, SourceMember[]>(_ => Empty);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should lock here. It's difficult to write correct thread safe code in a lot of places. I think we should lock when calling CreateMap.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already lock there but this is another place that's a static cache. Another option would be just to get rid of the cache.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was to not look for the attribute every time it tries to match the members to map. So it will be slower without the cache. But my point point is more general. A coarser grained lock would make the code easier to write and understand. That's why I added a global lock before each CreateMap. So we don't have to worry about concurrency at every point.

&& !ExcludedTypes.Contains(initialTypes.SourceType)
&& !ExcludedTypes.Contains(initialTypes.DestinationType))
{
return Configuration.CreateInlineMap(_typeMapRegistry, initialTypes);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would lock(this) here, so all CreateMap calls are serialized, closed generics, conventions and inline.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. I got rid of the cache, it's just not obvious.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah but that's the value factory for the locking concurrent dictionary. The lock is already there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I know there's a lock for the type pair, I'm just not sure that's enough. I'll have to think about it some more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's enough. A GetType map for some other types might call CreateMap for these initialTypes. And then you have concurrent CreateMap calls again.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing, I don't think we need a Lazy here. A regular bool? should do. It's a local, only one thread will access it and the mappers collection is immutable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah you're right, I missed the other locks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use the hasMapper in two places though? That would look a little odd, I might need a func or something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a problem with

 var hasMapper = (FindMapper(initialTypes) != null);

Or simply calling it twice as before.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@jbogard
Copy link
Contributor Author

jbogard commented Nov 15, 2017

Good to go?

@jbogard jbogard added this to the 6.2.1 milestone Nov 15, 2017
@lbargaoanu
Copy link
Contributor

It's not a big deal, but...

@jbogard jbogard merged commit 1746846 into master Nov 15, 2017
@jbogard jbogard deleted the InlineMapsForProjectTo branch November 15, 2017 14:54
@lock
Copy link

lock bot commented May 5, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators May 5, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inline maps broke missing type map creation for ProjectTo.

2 participants