-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
Conversation
b2fe55d
to
ba11a58
Compare
There was a problem hiding this 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
src/Servers/Kestrel/Kestrel/test/KestrelConfigurationBuilderTests.cs
Outdated
Show resolved
Hide resolved
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 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. |
There was a problem hiding this 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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) => |
There was a problem hiding this comment.
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?
e953190
to
97577a4
Compare
src/Servers/Kestrel/Core/src/Internal/ServerAddressesCollection.cs
Outdated
Show resolved
Hide resolved
1f05613
to
bac3966
Compare
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. 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 😄 |
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. |
Debouncing needs to be built into the system and shouldnt be something that everyone needs to handle (e.g. #10620) |
bac3966
to
860bf97
Compare
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:
|
860bf97
to
39fa43e
Compare
Co-Authored-By: Andrew Stanton-Nurse <[email protected]>
Co-Authored-By: Chris Ross <[email protected]>
72c3acb
to
f80f222
Compare
API seems minimal and looks good to me. |
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