mirror of
https://github.com/DuendeSoftware/products
synced 2026-05-24 01:18:22 +00:00
Merge pull request #2229 from DuendeSoftware/wca/diagnostics-operation-canceled
Catch potential OperationCanceledException in DiagnosticHostedService
This commit is contained in:
commit
def100a79c
2 changed files with 67 additions and 7 deletions
|
|
@ -13,19 +13,30 @@ internal class DiagnosticHostedService(DiagnosticSummary diagnosticSummary, IOpt
|
|||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
using var timer = new PeriodicTimer(options.Value.Diagnostics.LogFrequency);
|
||||
while (!stoppingToken.IsCancellationRequested && await timer.WaitForNextTickAsync(stoppingToken))
|
||||
try
|
||||
{
|
||||
try
|
||||
while (!stoppingToken.IsCancellationRequested && await timer.WaitForNextTickAsync(stoppingToken))
|
||||
{
|
||||
await diagnosticSummary.PrintSummary();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "An error occurred while logging the diagnostic summary: {Message}", ex.Message);
|
||||
try
|
||||
{
|
||||
await diagnosticSummary.PrintSummary();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "An error occurred while logging the diagnostic summary: {Message}",
|
||||
ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// When stopping this hosted service, "await timer.WaitForNextTickAsync(stoppingToken)" can throw an OperationCanceledException.
|
||||
}
|
||||
}
|
||||
|
||||
// Added for testing purposes to be able to call ExecuteAsync directly.
|
||||
internal Task ExecuteForTestOnly(CancellationToken stoppingToken) => ExecuteAsync(stoppingToken);
|
||||
|
||||
public override async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await diagnosticSummary.PrintSummary();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
using System.Text.Json;
|
||||
using Duende.IdentityServer.Configuration;
|
||||
using Duende.IdentityServer.Licensing.V2.Diagnostics;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace IdentityServer.UnitTests.Licensing.V2;
|
||||
|
||||
public class DiagnosticHostedServiceTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_ShouldNotThrowOperationCancelledException()
|
||||
{
|
||||
var diagnosticSummaryLogger = new NullLogger<DiagnosticSummary>();
|
||||
var firstDiagnosticEntry = new TestDiagnosticEntry();
|
||||
var secondDiagnosticEntry = new TestDiagnosticEntry();
|
||||
var thirdDiagnosticEntry = new TestDiagnosticEntry();
|
||||
var entries = new List<IDiagnosticEntry>
|
||||
{
|
||||
firstDiagnosticEntry,
|
||||
secondDiagnosticEntry,
|
||||
thirdDiagnosticEntry
|
||||
};
|
||||
var diagnosticSummary = new DiagnosticSummary(DateTime.UtcNow, entries, new IdentityServerOptions(), new StubLoggerFactory(diagnosticSummaryLogger));
|
||||
|
||||
var options = Options.Create(new IdentityServerOptions());
|
||||
var logger = new NullLogger<DiagnosticHostedService>();
|
||||
|
||||
var service = new DiagnosticHostedService(diagnosticSummary, options, logger);
|
||||
|
||||
using var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(100);
|
||||
|
||||
var exception = await Record.ExceptionAsync(async () =>
|
||||
{
|
||||
await service.ExecuteForTestOnly(cts.Token);
|
||||
});
|
||||
|
||||
exception.ShouldBeNull();
|
||||
}
|
||||
|
||||
private class TestDiagnosticEntry : IDiagnosticEntry
|
||||
{
|
||||
public Task WriteAsync(DiagnosticContext context, Utf8JsonWriter writer) => Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue