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

Host stopped and disposed twice when WebApplicationFactory<> is used with the minimal api #40271

Open
1 task done
ghost opened this issue Feb 16, 2022 · 15 comments
Open
1 task done
Labels
area-hosting Includes Hosting

Comments

@ghost
Copy link

ghost commented Feb 16, 2022

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Description
When using WebApplicationFactory<> together with the minimal api WebApplication, the underlying Host is stopped and disposed twice from separate threads.

This can lead to integration tests failing e.g. when there are custom IHostedServices registered. Dpending on the race condition, a particular instance of IHostedService can be in order: stopped, then disposed, then attempted to stop again from a different thread; or attempted to stop twice from different threads at the same time.

What happens under the hood

With minimal api and the WebApplicationFactory<Program>, the whole Program content is executed. It goes up to Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.WaitForShutdownAsync() and waits for the IHostApplicationLifetime.ApplicationStopping event.

The test runs and at the end the WebApplicationFactory is being disposed. It calls (with some wrapper classes skipped here for brevity) Microsoft.Extensions.Hosting.Internal.Host.StopAsync()

The Host.StopAsync() calls ApplicationLifetime.StopApplication(), and thus raises the beforementioned IHostApplicationLifetime.ApplicationStopping event, thus unblocking the "main" thread executing HostingAbstractionsHostExtensions.WaitForShutdownAsync(), which then... calls Host.StopAsync() again.

Expected Behavior

Host and any registered IHostedServices should be stopped and disposed once.

Steps To Reproduce

https://github.com/mateusz-duchnowski-trainline/disposing-host-twice-issue

run dotnet test

example output, where A is an IHostedService:

[xUnit.net 00:00:01.19] DisposingHostTwiceIssue.Tests: A started
[xUnit.net 00:00:01.28] DisposingHostTwiceIssue.Tests: A stopping
[xUnit.net 00:00:01.28] DisposingHostTwiceIssue.Tests: A stopping
[xUnit.net 00:00:01.50] DisposingHostTwiceIssue.Tests: A stopped
[xUnit.net 00:00:01.50] DisposingHostTwiceIssue.Tests: A stopped

Exceptions (if any)

No response

.NET Version

6.0.200-preview.22055.15

Anything else?

No response

@mkArtakMSFT mkArtakMSFT added the area-web-frameworks *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels label Feb 16, 2022
@martincostello
Copy link
Member

This sounds a bit like #37631.

@ghost
Copy link
Author

ghost commented Feb 17, 2022

Hi @martincostello,
Looks similar. But the main issue here (which is not mentioned in #37631) is that it comes from two threads and that it affects both methods: StopAsync and DisposeAsync. So one thread can be executing StopAsync and the other one can start executing StopAsync too, or even call Dispose in the meantime.

It would be strange having to implement IHostedServices with that in mind, just for the integration test purposes.

@ghost
Copy link

ghost commented Feb 17, 2022

Thanks for contacting us.
We're moving this issue to the .NET 7 Planning milestone for future evaluation / consideration. Because it's not immediately obvious that this is a bug in our framework, we would like to keep this around to collect more feedback, which can later help us determine the impact of it. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

@dmitriyse
Copy link

Confirms, the problem exists. I am facing with the problem in the same scenario.

  1. .Net 6 minimal api (.Net 6 Web App template)
  2. builder.Services.AddHostedService(); // used to register the IHostedService
  3. WebApplicationFactory in xUnit test
  4. IHostedService.StopAsync <-- called twice

@federicojoselucia
Copy link

I'm experiencing the same issue.

@ghost
Copy link

ghost commented Oct 11, 2022

Thanks for contacting us.
We're moving this issue to the .NET 8 Planning milestone for future evaluation / consideration. Because it's not immediately obvious that this is a bug in our framework, we would like to keep this around to collect more feedback, which can later help us determine the impact of it. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

@salarzobir
Copy link

+1 any progress or a workaround for this?

@mitchdenny
Copy link
Member

mitchdenny commented May 24, 2023

Does anyone have a minimal repro of this - the repro linked in the opening post doesn't appear to be there anymore.

@salarzobir
Copy link

@captainsafia captainsafia added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc and removed area-web-frameworks *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels labels Jun 20, 2023
@EraYaN
Copy link

EraYaN commented Nov 2, 2023

This also happens without using minimal API, while using an old school Startup class.

@AntonSmolkov
Copy link

Same here. Dotnet 7, Xunit, WebApplicationFactory

@salarzobir
Copy link

Same problem still exists in .NET 8
I wonder if there is a workaround using the new IHostedLifecycleService ???

@mr-dokara
Copy link

Same problem in .NET 8 with Xunit, WebApplicationFactory. I had to do workaround through modifying StartAsync and StopAsync methods of the problem service

@AqlaSolutions
Copy link

Same problem

@halter73
Copy link
Member

I changed the labels because this issue has seen a bit activity over the years, and I just got pinged about it. I think the proper fix belongs in dotnet/runtime's Host.cs, but we could also reconsider #37631.

@halter73 halter73 removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc labels Sep 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-hosting Includes Hosting
Projects
No open projects
Status: No status
Development

No branches or pull requests