| File: ServiceClient\DashboardDataSourceInitializer.cs | Web Access |
| Project: src\src\Aspire.Dashboard\Aspire.Dashboard.csproj (Aspire.Dashboard) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. namespace Aspire.Dashboard.ServiceClient; internal sealed class DashboardDataSourceInitializer( DashboardDataSourcePool dataSourcePool, IHostApplicationLifetime applicationLifetime, ILogger<DashboardDataSourceInitializer> logger) : IHostedService, IDisposable { private CancellationTokenRegistration _startedRegistration; public async Task StartAsync(CancellationToken cancellationToken) { await dataSourcePool.InitializeAsync(cancellationToken).ConfigureAwait(false); // Publishing from ApplicationStarted ensures a failed Kestrel bind doesn't leave an empty attempted run // in history. It is safe to publish this late because the current run is created from in-memory metadata; // run.json is only needed by a later Dashboard process to discover this run as historical. Pruning is slower // file system housekeeping, so keep that work off the startup callback. _startedRegistration = applicationLifetime.ApplicationStarted.Register(static state => { var (pool, log) = ((DashboardDataSourcePool, ILogger))state!; pool.PublishRun(); _ = Task.Run(() => { try { pool.PruneExpiredRuns(); } catch (Exception ex) { // Nothing awaits this, so an unhandled exception would crash the process. log.LogWarning(ex, "Failed to prune expired dashboard runs."); } }); }, (dataSourcePool, (ILogger)logger)); } public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; public void Dispose() => _startedRegistration.Dispose(); }