Skip to content

Commit 72c3acb

Browse files
committed
Default config reloadOnChange to false
1 parent f9d72d8 commit 72c3acb

File tree

2 files changed

+63
-6
lines changed

2 files changed

+63
-6
lines changed

src/Servers/Kestrel/Core/src/KestrelServerOptions.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,11 @@ private void EnsureDefaultCert()
208208
/// <summary>
209209
/// Creates a configuration loader for setting up Kestrel that takes an <see cref="IConfiguration"/> as input.
210210
/// This configuration must be scoped to the configuration section for Kestrel.
211-
/// Kestrel will dynamically update endpoint bindings when configuration changes.
212-
/// This will only reload endpoints defined in the "Endpoints" section of your <paramref name="config"/>. Endpoints defined in code will not be reloaded.
213-
/// Call <see cref="Configure(IConfiguration, bool)"/> to disable dynamic endpoint binding updates.
211+
/// Call <see cref="Configure(IConfiguration, bool)"/> to enable dynamic endpoint binding updates.
214212
/// </summary>
215213
/// <param name="config">The configuration section for Kestrel.</param>
216214
/// <returns>A <see cref="KestrelConfigurationLoader"/> for further endpoint configuration.</returns>
217-
public KestrelConfigurationLoader Configure(IConfiguration config) => Configure(config, true);
215+
public KestrelConfigurationLoader Configure(IConfiguration config) => Configure(config, reloadOnChange: false);
218216

219217
/// <summary>
220218
/// Creates a configuration loader for setting up Kestrel that takes an <see cref="IConfiguration"/> as input.

src/Servers/Kestrel/Core/test/KestrelServerTests.cs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ public void StartingServerInitializesHeartbeat()
458458
}
459459

460460
[Fact]
461-
public async Task ReloadsOnConfigurationChangeByDefault()
461+
public async Task ReloadsOnConfigurationChangeWhenOptedIn()
462462
{
463463
var currentConfig = new ConfigurationBuilder().AddInMemoryCollection(new[]
464464
{
@@ -501,7 +501,7 @@ public async Task ReloadsOnConfigurationChangeByDefault()
501501
ApplicationServices = serviceCollection.BuildServiceProvider(),
502502
};
503503

504-
options.Configure(mockConfig.Object);
504+
options.Configure(mockConfig.Object, reloadOnChange: true);
505505

506506
var mockTransports = new List<Mock<IConnectionListener>>();
507507
var mockTransportFactory = new Mock<IConnectionListenerFactory>();
@@ -611,6 +611,65 @@ public async Task ReloadsOnConfigurationChangeByDefault()
611611
}
612612
}
613613

614+
[Fact]
615+
public async Task DoesNotReloadOnConfigurationChangeByDefault()
616+
{
617+
var currentConfig = new ConfigurationBuilder().AddInMemoryCollection(new[]
618+
{
619+
new KeyValuePair<string, string>("Endpoints:A:Url", "http://*:5000"),
620+
new KeyValuePair<string, string>("Endpoints:B:Url", "http://*:5001"),
621+
}).Build();
622+
623+
var mockConfig = new Mock<IConfiguration>();
624+
mockConfig.Setup(c => c.GetSection(It.IsAny<string>())).Returns<string>(name => currentConfig.GetSection(name));
625+
mockConfig.Setup(c => c.GetChildren()).Returns(() => currentConfig.GetChildren());
626+
627+
var mockLoggerFactory = new Mock<ILoggerFactory>();
628+
mockLoggerFactory.Setup(m => m.CreateLogger(It.IsAny<string>())).Returns(Mock.Of<ILogger>());
629+
630+
var serviceCollection = new ServiceCollection();
631+
serviceCollection.AddSingleton(mockLoggerFactory.Object);
632+
serviceCollection.AddSingleton(Mock.Of<ILogger<KestrelServer>>());
633+
634+
var options = new KestrelServerOptions
635+
{
636+
ApplicationServices = serviceCollection.BuildServiceProvider(),
637+
};
638+
639+
options.Configure(mockConfig.Object);
640+
641+
var mockTransports = new List<Mock<IConnectionListener>>();
642+
var mockTransportFactory = new Mock<IConnectionListenerFactory>();
643+
mockTransportFactory
644+
.Setup(transportFactory => transportFactory.BindAsync(It.IsAny<EndPoint>(), It.IsAny<CancellationToken>()))
645+
.Returns<EndPoint, CancellationToken>((e, token) =>
646+
{
647+
var mockTransport = new Mock<IConnectionListener>();
648+
mockTransport
649+
.Setup(transport => transport.AcceptAsync(It.IsAny<CancellationToken>()))
650+
.Returns(new ValueTask<ConnectionContext>(result: null));
651+
mockTransport
652+
.Setup(transport => transport.EndPoint)
653+
.Returns(e);
654+
655+
mockTransports.Add(mockTransport);
656+
657+
return new ValueTask<IConnectionListener>(mockTransport.Object);
658+
});
659+
660+
// Don't use "using". Dispose() could hang if test fails.
661+
var server = new KestrelServer(Options.Create(options), new List<IConnectionListenerFactory>() { mockTransportFactory.Object }, mockLoggerFactory.Object);
662+
663+
await server.StartAsync(new DummyApplication(), CancellationToken.None).DefaultTimeout();
664+
665+
mockTransportFactory.Verify(f => f.BindAsync(new IPEndPoint(IPAddress.IPv6Any, 5000), It.IsAny<CancellationToken>()), Times.Once);
666+
mockTransportFactory.Verify(f => f.BindAsync(new IPEndPoint(IPAddress.IPv6Any, 5001), It.IsAny<CancellationToken>()), Times.Once);
667+
668+
mockConfig.Verify(c => c.GetReloadToken(), Times.Never);
669+
670+
await server.StopAsync(CancellationToken.None).DefaultTimeout();
671+
}
672+
614673
private static KestrelServer CreateServer(KestrelServerOptions options, ILogger testLogger)
615674
{
616675
return new KestrelServer(Options.Create(options), new List<IConnectionListenerFactory>() { new MockTransportFactory() }, new LoggerFactory(new[] { new KestrelTestLoggerProvider(testLogger) }));

0 commit comments

Comments
 (0)