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

Breaking change: Throw when resolving on a disposed service provider #45116

Merged
merged 18 commits into from
Dec 4, 2020

Conversation

maryamariyan
Copy link
Member

@maryamariyan maryamariyan commented Nov 23, 2020

  • Resolving Services after ServiceProvider is Disposed should throw with ObjectDisposedException

@davidfowl, for testing I prepared a test similar to the repro code you provided earlier in this comment

Similar to the use case you were illustrating there, this use case (before this PR change) would also result in a deadlock. Here we try to call Dispose while the singleton lock ResolvedServices is taken). As shown in this test now it would throw ObjectDisposedException instead.

- Resolving Services after ServiceProvider is Disposed should throw with ObjectDisposedException
@ghost
Copy link

ghost commented Nov 23, 2020

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

Issue Details
  • Resolving Services after ServiceProvider is Disposed should throw with ObjectDisposedException

@davidfowl, for testing I took a test similar to the repro code you provided earlier in this comment

Similar to the use case you were illustrating there where the singleton lock would be used, before this PR change, the test would result in a deadlock since Dispose would use the same "ResolvedServices" singleton lock when resolving singleton services. As shown in this test now it would throw ObjectDisposedException instead.

Author: maryamariyan
Assignees: -
Labels:

area-Extensions-DependencyInjection

Milestone: -

@maryamariyan
Copy link
Member Author

Thanks @davidfowl. I think the PR is ready for another now.

{
public Foo1()
{
Thread.Sleep(5000);
Copy link
Member

Choose a reason for hiding this comment

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

What is this testing?

Copy link
Member Author

@maryamariyan maryamariyan Dec 1, 2020

Choose a reason for hiding this comment

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

If during resolve of this service, service provider gets disposed on another thread, the test asserts that we dispose of the service as well.

Copy link
Member

Choose a reason for hiding this comment

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

But the way the test is written above, this sleep will happen inline and then the object will be returned on line 276.

Once the object is returned, then you are starting a new thread to dispose the service provider.

So I don't think the sleep is doing anything beneficial.

Copy link
Member

Choose a reason for hiding this comment

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

Good catch, we need to kick off 2 threads.

Copy link
Member Author

@maryamariyan maryamariyan Dec 2, 2020

Choose a reason for hiding this comment

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

If during resolve of this service, service provider gets disposed on another thread, the test asserts that we dispose of the service as well.

Removed this test and instead used tests below to also assert that the service (for both IDisposable and IAsyncDisposable cases) get disposed:

  • GetAsyncService_DisposeAsyncOnSameThread_ThrowsAndDoesNotHangAndDisposeAsyncGetsCalled
  • GetService_DisposeOnSameThread_ThrowsAndDoesNotHangAndDisposeGetsCalled

The removed case would have been very similar in outcome to the two test cases I mentioned above, so perhaps OK that we don't add it.

@eerhardt eerhardt added the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Nov 30, 2020
@ghost ghost added the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Nov 30, 2020
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.

This looks good to me. Nice work, @maryamariyan.

@maryamariyan maryamariyan merged commit e280e61 into dotnet:master Dec 4, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Jan 3, 2021
@ericstj ericstj added this to the 6.0.0 milestone Sep 29, 2021
@maryamariyan maryamariyan removed the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Nov 2, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Extensions-DependencyInjection breaking-change Issue or PR that represents a breaking API or functional change over a prerelease.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants