-
Notifications
You must be signed in to change notification settings - Fork 7
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
TeardownAsync and Host.DisposeAsync race #18
Comments
Hi @kvpt, |
OK, so as far as I can tell, there's no way to prevent the host from being disposed once the application is stopped. It's a bit strange that it seems to happen non-deterministically (I would have expected that it would happen either before the call to I thought we could to take advantage of
This seemed ideal, except that the cancellation token's callbacks are synchronous, but the teardown is async, so it doesn't really help. Using a hosted service is an interesting idea. However, we have no control over the order in which the hosted services are stopped. If the Tagging @AleRoe who introduced the teardown feature and might be interested in this. |
It is indeed the case if Looking at the code for |
Actually, that won't help, at least for older .NET versions. |
I think it would be an acceptable limitation. Calling |
Hi,
I also encounter the issue mentioned previously in #16 when using InitAndRunAsync method.
I confirm that under certain conditions there can be a race between TeardownAsync and DisposeAsync on the Host, the parallel stacks bellow illustrate this fact.
![Capture d'écran 2024-04-03 231550](https://private-user-images.githubusercontent.com/1446221/319363379-43813aea-995c-4b3e-9e86-024b92bb006f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzg5Nzc5MDgsIm5iZiI6MTczODk3NzYwOCwicGF0aCI6Ii8xNDQ2MjIxLzMxOTM2MzM3OS00MzgxM2FlYS05OTVjLTRiM2UtOWU4Ni0wMjRiOTJiYjAwNmYucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDIwOCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTAyMDhUMDEyMDA4WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MjYxOTZiOTM2MTRmYTg0ODFhNGUyMmJhOGMxNGM0Mzc3MGNmMGE5ZmQzZTQ5NjkyOTg1OGM2ZDM1MTE0ODUzZiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.FUS4RLfwrnmDVqCsJZqDwk0KB9IXVe5XTPh8VVP_fb0)
The InitAndRunAsync method call WaitForShutdownAsync to ensure that the Teardown happen after the shutdown.
But there is no guarantee that the host has not been disposed between the WaitForShutdownAsync ending and the call to TeardownAsync method.
The StopAsync method of the Host call the StopAsync method of each registered HostedService and the application Lifecycle.
This ensure that each HostedService and Lifecycle has stopped correctly when StopAsync call end.
But as this library doesn't use HostedService mecanism it doesn't prevent the call to dispose before the Teardown has executed.
For me it doesn't happen in conventional environment but 95% of the time when I run my integration tests (that use Xunit and Alba) in debug mode.
I tried to reproduce the case in the unit tests of the solution.
I not have found a proper way to trigger the problem without adding a hard coded delay to ensure that the dispose always win the race against WaitForShutdownAsync.
To reproduce the issue :
Adding a delay before the teardown inside the InitAndRunAsync method.
Run this test:
Implementing a HostedService to call TeardownAsync would likely solve the issue but I'm not sure if it a practical solution here because it will prevent the ability to call TeardownAsync when wanted.
I also wonder if it is possible to prevent calling the teardown method when after the init is done we notice that there is no AsyncInitializer that implement IAsyncTeardown.
In my case and in #16 also, we don't implement IAsyncTeardown at all.
For now my workaround is to fallback to the old way as I don't use teardown.
The text was updated successfully, but these errors were encountered: