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

Fixes DI deadlock when resolving singletons #46157

Merged
merged 10 commits into from
Jan 21, 2021

Conversation

maryamariyan
Copy link
Member

@maryamariyan maryamariyan commented Dec 16, 2020

Introducing per singleton lock for the code path which resolves singletons.

The repro test case in #35986 (comment) gets fixed with this change.

Fixes: #35986

@ghost
Copy link

ghost commented Dec 16, 2020

Tagging subscribers to this area: @eerhardt, @maryamariyan
See info in area-owners.md if you want to be subscribed.

Issue Details

Introducing per singleton lock for the code path which resolves singletons.

The repro test case in #35986 (comment) gets fixed with this change.

TODO:

  • slight code cleanup
  • consider preparing a simpler test case.
  • then switch out from draft PR.

Fixes: #35986

Author: maryamariyan
Assignees: maryamariyan
Labels:

area-Extensions-DependencyInjection

Milestone: -

@davidfowl
Copy link
Member

I think you should try to use the call site itself as the lock for singletons

@maryamariyan maryamariyan marked this pull request as ready for review January 4, 2021 14:23
@eerhardt
Copy link
Member

eerhardt commented Jan 7, 2021

Since this is pretty core logic that affects a lot of ASP.NET, is it possible to run all of ASP.NET's tests on this change before merging? How easy would that be @davidfowl @Tratcher @pranavkm ?

Copy link
Contributor

@pranavkm pranavkm left a comment

Choose a reason for hiding this comment

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

How easy would that be

You could create a draft PR pointing to a build of this package and let the public CI do it's job. That shouldn't be too hard and could instill some confidence prior to merging this change.

- Remove unrelated test
- Code cleanup
maryamariyan and others added 2 commits January 14, 2021 15:51
…I.Tests/ServiceProviderContainerTests.cs

Co-authored-by: Eric Erhardt <eric.erhardt@microsoft.com>
@maryamariyan
Copy link
Member Author

maryamariyan commented Jan 19, 2021

You could create a draft PR pointing to a build of this package and let the public CI do it's job. That shouldn't be too hard and could instill some confidence prior to merging this change.

As part of this exercise I downloaded the DI package from this PR (postfixed with -ci). But it's not straightforward to test the package against aspnetcore CI since they also need the package to point to a nuget source somewhere the CI can access. 

Testing the DI package against all aspnetcore projects locally is a bit of a hassle too. I'm working with @pranavkm on this and perhaps worst case we could merge this, and test off the published package from merge, and if problems occur then revert accordingly.

@maryamariyan
Copy link
Member Author

as per @eerhardt 's recommendation updated the tests to use two ManualResetEvents so we can enforce the expected order of execution we want to test for deadlock.

@maryamariyan
Copy link
Member Author

maryamariyan commented Jan 20, 2021

Added an aspnetcore PR (dotnet/aspnetcore#29437) which triggers their tests on changes made here.

UPDATE on status of the aspnetcore PR:

  • DI related tests passed
  • All of the failures are template tests (performing restore) and runtime pack tests (just complaining on the way the PR includes the nupkg packages).

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

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

LGTM.

The tests changes look good, and are deterministic now. Thanks for the good work here.

@davidfowl
Copy link
Member

If github supported gifs, I would post a happy dance! This is a long standing issue with the DI container that has crippled many services.

@maryamariyan maryamariyan merged commit ef88908 into dotnet:master Jan 21, 2021
var lockType = RuntimeResolverLock.Root;
bool lockTaken = false;

if ((context.AcquiredLocks & lockType) == 0)
Copy link
Member

Choose a reason for hiding this comment

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

@pakrym notice that this check here is problematic and can no longer be used since we're taking a unique lock per singleton. We don't want to skip it here anymore.

Copy link
Member Author

@maryamariyan maryamariyan Jan 21, 2021

Choose a reason for hiding this comment

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

I see. I'll fix both comments with test. Thanks.

UPDATE:

Added PR #47310 to address these comments

@ghost ghost locked as resolved and limited conversation to collaborators Feb 21, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Deadlock when creating typed HttpClient with DI and HttpClientFactory
4 participants