Skip to content

Commit

Permalink
Don't log error from background service if host is gracefully stopped…
Browse files Browse the repository at this point in the history
… while still starting (#100032)
  • Loading branch information
ProsserCJ authored Mar 27, 2024
1 parent c4796a3 commit 78c2c98
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ internal sealed class Host : IHost, IAsyncDisposable
private IEnumerable<IHostedService>? _hostedServices;
private IEnumerable<IHostedLifecycleService>? _hostedLifecycleServices;
private bool _hostStarting;
private volatile bool _stopCalled;
private bool _hostStopped;

public Host(IServiceProvider services,
Expand Down Expand Up @@ -190,7 +189,7 @@ private async Task TryExecuteBackgroundServiceAsync(BackgroundService background
{
// When the host is being stopped, it cancels the background services.
// This isn't an error condition, so don't log it as an error.
if (_stopCalled && backgroundTask.IsCanceled && ex is OperationCanceledException)
if (_applicationLifetime.ApplicationStopping.IsCancellationRequested && backgroundTask.IsCanceled && ex is OperationCanceledException)
{
return;
}
Expand All @@ -217,7 +216,6 @@ private async Task TryExecuteBackgroundServiceAsync(BackgroundService background
/// </summary>
public async Task StopAsync(CancellationToken cancellationToken = default)
{
_stopCalled = true;
_logger.Stopping();

CancellationTokenSource? cts = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,39 @@ public async Task StartOnBackgroundServiceThatDoesNotCallBase()
}
}

/// <summary>
/// Tests that when a BackgroundService is cancelled when stopping a host which has not finished starting, it does not log an error
/// </summary>
[Fact]
public async Task HostNoErrorWhenStartingServiceIsCanceledAsPartOfStop()
{
TestLoggerProvider logger = new TestLoggerProvider();

using IHost host = CreateBuilder()
.ConfigureLogging(logging =>
{
logging.AddProvider(logger);
})
.ConfigureServices(services =>
{
services.AddHostedService<WorkerTemplateService>();
services.AddHostedService<SlowStartService>();
})
.Build();

IHostApplicationLifetime lifetime = host.Services.GetRequiredService<IHostApplicationLifetime>();
_ = host.StartAsync();
lifetime.StopApplication();
await Task.Delay(TimeSpan.FromMilliseconds(100));
await host.WaitForShutdownAsync();

foreach (LogEvent logEvent in logger.GetEvents())
{
Assert.True(logEvent.LogLevel < LogLevel.Error);
Assert.NotEqual("BackgroundServiceFaulted", logEvent.EventId.Name);
}
}

private IHostBuilder CreateBuilder(IConfiguration config = null)
{
return new HostBuilder().ConfigureHostConfiguration(builder => builder.AddConfiguration(config ?? new ConfigurationBuilder().Build()));
Expand Down Expand Up @@ -1637,5 +1670,15 @@ private class BackgroundServiceDoesNotCallBase : BackgroundService

public override Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}

private class SlowStartService : IHostedService
{
public async Task StartAsync(CancellationToken cancellationToken)
{
await Task.Delay(TimeSpan.FromSeconds(10), CancellationToken.None);
}

public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
}
}

0 comments on commit 78c2c98

Please sign in to comment.