Skip to content

Stop the host when the single session server service finishes #226

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

Merged
merged 2 commits into from
Apr 7, 2025

Conversation

stephentoub
Copy link
Contributor

@stephentoub stephentoub commented Apr 7, 2025

@halter73, is this the right way to do it?

Contributes to #221
Closes #155

@stephentoub stephentoub requested a review from halter73 April 7, 2025 01:50
@halter73
Copy link
Contributor

halter73 commented Apr 7, 2025

The host should do this for you.

https://github.com/dotnet/runtime/blob/367e0a8a23e444a94c029fcb72dcb4ac66bd6717/src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs#L236

However, #221 and #155 were fixed by #225. I hadn't really noticed the long shutdown times (edit: with SSE which is not relevant to this PR) before because I typically closed the response stream on the client side before shutting down the server. The ConnectCallback Stream.DisposeAsync bug uncovered the long shutdown issue for me. I left a small note in my PR descriptions about fixing this.

  • Use ApplicationStopping token for SSE responses. SignalR does the same thing FWIW

And then this in the comment:

// If the server is shutting down, we need to cancel all SSE connections immediately without waiting for HostOptions.ShutdownTimeout
// which defaults to 30 seconds.
using var sseCts = CancellationTokenSource.CreateLinkedTokenSource(context.RequestAborted, hostApplicationLifetime.ApplicationStopping);

https://github.com/modelcontextprotocol/csharp-sdk/pull/225/files#diff-f740d1d73af0aac882eeee83a3293823ebb6fba888daddd601a7da3af6c0a853R66

I can close the two issues as fixed by my PR if you want. Saving 30 seconds during shutdown is dramatic.

@halter73
Copy link
Contributor

halter73 commented Apr 7, 2025

Sorry, I just noticed both those issues were stdio servers. I'm not sure what's going on there. I do think changes similar to dotnet/cli#10720 might help.

@stephentoub
Copy link
Contributor Author

The host should do this for you.

When StopAsync is called. StopAsync isn't being called.

I'm not sure what's going on there.

As far as I can tell, the hosting infrastructure doesn't automatically exit when a background service exits.

I do think changes similar to dotnet/cli#10720 might help.

It would mask it, certainly. But I think the server should be able to gracefully exit on its own.
#155 (comment)

Copy link
Contributor

@halter73 halter73 left a comment

Choose a reason for hiding this comment

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

It took me a second, but now I see the logic behind this change. As you could probably tell, when I left my first comment, I was still thinking about HTTP scenarios. I'm not used to single-session servers 😆

@halter73
Copy link
Contributor

halter73 commented Apr 7, 2025

It'd be nice if we could have a test though. It should be easy enough to have a client close the stream and verify the server host stops within a timeout.

@stephentoub stephentoub merged commit 5d7c2a1 into modelcontextprotocol:main Apr 7, 2025
14 of 15 checks passed
@stephentoub stephentoub deleted the shutdownhost branch April 7, 2025 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Shutting down console application which uses mcpclient does not kill the stdio process
2 participants