Skip to content
This repository was archived by the owner on Dec 19, 2018. It is now read-only.

Catch exceptions while disposing #136

Merged
merged 1 commit into from
Jan 4, 2015

Conversation

Tragetaschen
Copy link
Contributor

Kestrel#9 revealed a shutdown problem when an exception is thrown during the final Dispose. This exception would omit setting the ManualResetEvent and the runtime would essentially deadlock.

This PR makes an exception during Dispose visible.

@@ -59,7 +59,14 @@ public void Main(string[] args)

appShutdownService.ShutdownRequested.Register(() =>
{
serverShutdown.Dispose();
Copy link
Member

Choose a reason for hiding this comment

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

Dispose should never throw. We should fix Kestrel

Copy link
Member

Choose a reason for hiding this comment

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

Yes, we should fix Kestrel so it doesn't throw. That said, since Hosting will be interacting with 3rd party components here we should make it more defensive, especially when the consequence is a hang.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah what @Tratcher said. Need to fix both sides.

@Tragetaschen
Copy link
Contributor Author

This isn't meant as a fix for the Kestrel bug.

The problem it tries to solve is that the Dispose exception cannot be noticed at the moment:

The RequestShutdown() calls the handler by Cancel'ing the CancellationTokenSource. An Exception during the Register'ed ShutdownRequested handler stops setting the ManualResetEvent and the program deadlocks. That's bad, so let's assume, there is at least a try/finally for the Set(). Now, when the CTS cancels, the Exceptions are thrown when all handlers ran. These exceptions unwind into the ignored Task and set this to the Faulted state. Currently, noone checks the ignored-Task's state, so the exceptions are propagated on the finalizer thread (ugh!). To safely check the exceptions, you would have to Wait() for the Task, otherwise, it's a race. But other parts of the program besides the ignored-Task can call RequestShutdown(). This means the ignored-Task might not run to an end and we are back to the deadlock.

I don't see it yet, but there sould be a better design here for exceptions during shutdown. Until then if a Dispose throws, this makes it possible to see the Exceptions at least.

}
catch (Exception ex)
{
Console.WriteLine("TODO: Dispose threw exception:\n{0}\n{1}", ex.Message, ex.StackTrace);
Copy link
Member

Choose a reason for hiding this comment

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

We might want to use ILogger instead of going directly to the Console.

@Tragetaschen Tragetaschen force-pushed the shutdown-dispose-exception branch from 3b194b4 to 44d2b4d Compare December 27, 2014 18:36
catch (Exception ex)
{
var logger = loggerFactory.Create<Program>();
logger.WriteError("TODO: Dispose threw exception:\n{0}\n{1}", ex.Message, ex.StackTrace);
Copy link
Contributor

Choose a reason for hiding this comment

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

Use Environment.NewLine instead of \n?

@Tragetaschen Tragetaschen force-pushed the shutdown-dispose-exception branch from 44d2b4d to ada59c7 Compare December 27, 2014 21:58
Environment.NewLine,
"TODO: Dispose threw exception:",
ex.Message, ex.StackTrace);
logger.WriteError(errorMessage);
Copy link
Member

Choose a reason for hiding this comment

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

This error message formatting doesn't look right. There is an overload that takes an exception object.

@Tragetaschen Tragetaschen force-pushed the shutdown-dispose-exception branch from ada59c7 to 6cd5744 Compare December 27, 2014 23:05
@Tratcher
Copy link
Member

Looks good.

@davidfowl
Copy link
Member

:shipit:

@davidfowl
Copy link
Member

@Tragetaschen has a CLA on file AFAIK /cc @Eilon I think this is good to merge

@Eilon
Copy link
Contributor

Eilon commented Dec 31, 2014

Yup CLA is good.

davidfowl added a commit that referenced this pull request Jan 4, 2015
@davidfowl davidfowl merged commit d9237b3 into aspnet:dev Jan 4, 2015
@Tragetaschen Tragetaschen deleted the shutdown-dispose-exception branch January 5, 2015 07:54
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants