Skip to content

Kestrel reloadable endpoint config #21072

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 16 commits into from
May 1, 2020
Merged

Kestrel reloadable endpoint config #21072

merged 16 commits into from
May 1, 2020

Conversation

halter73
Copy link
Member

@halter73 halter73 commented Apr 21, 2020

This PR allows Kestrel to observe changes to the config passed to KestrelServerOptions.Configure(IConfiguration), and bind/unbind/rebind to endpoints as necessary. This gives Kestrel the new ability to gracefully start and stop a subset of endpoints necessitating the new TransportManager and TransportConnectionManager.

If an endpoint is defined in code, even using the methods on KestrelConfigurationLoader, they will never be unbound or rebound due to configuration changes. Any code-based configuration that modifies endpoints defined in config, like callbacks passed to ConfigureEndpointDefaults, ConfigureHttpsDefaults and callbacks to configure modified named endpoints will be rerun.

Addresses #19376

@halter73 halter73 requested review from Tratcher and jkotalik April 21, 2020 21:05
@halter73 halter73 requested a review from analogrelay as a code owner April 21, 2020 21:05
@ghost ghost added the area-servers label Apr 21, 2020
@halter73 halter73 force-pushed the halter73/19376 branch 2 times, most recently from b2fe55d to ba11a58 Compare April 21, 2020 21:30
Copy link
Contributor

@analogrelay analogrelay left a comment

Choose a reason for hiding this comment

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

Smithed some words in the comments

@davidfowl davidfowl self-requested a review April 21, 2020 21:38
@davidfowl
Copy link
Member

If an endpoint is defined in code, even using the methods on KestrelConfigurationLoader, they will never be unbound or rebound due to configuration changes. Any code-based configuration that modifies endpoints defined in config, like callbacks passed to ConfigureEndpointDefaults, ConfigureHttpsDefaults and to configure named endpoints will be rerun.

Any plans to add an API that can do the same or is it purely configuration based?

@halter73
Copy link
Member Author

halter73 commented Apr 21, 2020

Any plans to add an API that can do the same or is it purely configuration based?

It would be nice to have. @Tratcher suggested this too, but there are now no immediate plans for a code-based API.

That said, this PR takes care of of a lot of the inner plumbing necessary to make it work. I think we could easily expose KestrelServerOptions.Listen-style APIs on a singleton.

Designing the API to unbind is a bit trickier. We could create a new API to query existing endpoints. We could also leverage IServerAddressFeature and make the address the key for unbinding.

Copy link
Member

@Tratcher Tratcher left a comment

Choose a reason for hiding this comment

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

Yeah, please file a separate issue for code based rebinding. I expect the larger proxy customers will be doing primarily code based setup rather than config based.

using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(_stopCts.Token, timeoutCts.Token);

// TODO: It would be nice to start binding to new endpoints immediately and reconfigured endpoints as soon
Copy link
Member

Choose a reason for hiding this comment

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

Except there may be conflicts.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ofc. We would have to write the algorithm to sequence unbinding and binding only for endpoints that are being reconfigured instead of newly added. If it was a simple as binding and unbinding in parallel. I would have already done it.

That's probably not worth the effort. What might still be worth doing is adding a TransportManager method that just unbinds endpoints. We could unbind first, then bind in parallel to draining the old connections.

Copy link
Member

Choose a reason for hiding this comment

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

We're going to get asked if non-destructive updates are possible. E.g. if all I did was change the cert file, why do I have to drop the socket? This will make even more sense when we get to config based SNI, if all I do is add one more host/cert to the list why should everything be torn down.

Not saying this is something we have to address right now, but we should at least think about if all changes are equal.

config.AddJsonFile("appsettings.json", optional: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.UseKestrel((context, options) =>
Copy link
Member

Choose a reason for hiding this comment

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

Can you show setting kestrel's reloadOnChange option, even it it's to the default?

@halter73 halter73 force-pushed the halter73/19376 branch 8 times, most recently from e953190 to 97577a4 Compare April 22, 2020 02:03
@halter73 halter73 force-pushed the halter73/19376 branch 2 times, most recently from 1f05613 to bac3966 Compare April 24, 2020 20:43
@davidfowl
Copy link
Member

Looking at this logic I don't know we didn't use IOptions<T> for this originally... Seems like this should be IOptionsMonitor<T> would be the replacement instead of doing what this is doing.

Also https://github.com/dotnet/aspnetcore/pull/21072/files#diff-b2d7bf739c9e417a24fca24244fb808dR265

We have a helper that does reload token management and change notification that may be better to use https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.primitives.changetoken.onchange?view=dotnet-plat-ext-3.1. Of course, if you use the IOptionsMonitor this happens for you 😄

@Tratcher
Copy link
Member

Yeah, at the time I didn't know the config system well enough to know if it could handle this. In hindsight I probably could have made it work. You'd still have to diff and debounce though.

@davidfowl
Copy link
Member

Debouncing needs to be built into the system and shouldnt be something that everyone needs to handle (e.g. #10620)

@ghost
Copy link

ghost commented Apr 28, 2020

Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:

  • The PR contains changes to the reference-assembly that describe the API change. Or, you have included a snippet of reference-assembly-style code that illustrates the API change.
  • The PR describes the impact to users, both positive (useful new APIs) and negative (breaking changes).
  • Someone is assigned to "champion" this change in the meeting, and they understand the impact and design of the change.

@analogrelay
Copy link
Contributor

API seems minimal and looks good to me.

@analogrelay analogrelay added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews labels Apr 30, 2020
@halter73 halter73 merged commit 100823a into master May 1, 2020
@halter73 halter73 deleted the halter73/19376 branch May 1, 2020 03:42
@amcasey amcasey added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions and removed area-runtime labels Jun 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-approved API was approved in API review, it can be implemented area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants