diff --git a/Directory.Packages.props b/Directory.Packages.props index e14f3e6..73276d1 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -30,7 +30,9 @@ - + + + @@ -78,9 +80,7 @@ - - - + diff --git a/aspire/DotNetBoost.Settings.AppHost/AppHost.cs b/aspire/DotNetBoost.Settings.AppHost/AppHost.cs index 85a9b5f..cbbcf0a 100644 --- a/aspire/DotNetBoost.Settings.AppHost/AppHost.cs +++ b/aspire/DotNetBoost.Settings.AppHost/AppHost.cs @@ -85,6 +85,11 @@ .WithReference(redis) .WaitFor(redis) .WithEnvironment("Settings__EncryptionKey", encryptionKey) + // /health carries the AddDbContextCheck registered in samples/SampleApp/Program.cs, so + // this is what makes the dashboard's WaitFor(api) below hold until Postgres actually + // answers rather than merely until the process is up. MapDefaultEndpoints only maps + // /health in Development — drop this line if you ever publish this AppHost. + .WithHttpHealthCheck("/health") .WithExternalHttpEndpoints(); // ── Dashboard — clients/dashboard (Nuxt) ───────────────────────────────────── diff --git a/samples/SampleApp/Program.cs b/samples/SampleApp/Program.cs index fc99f60..60246cc 100644 --- a/samples/SampleApp/Program.cs +++ b/samples/SampleApp/Program.cs @@ -1,5 +1,8 @@ using DotNetBoost.Settings.Core.Interfaces; using Microsoft.EntityFrameworkCore; +using OpenTelemetry; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; using SampleApp; using SampleApp.Caching; using SampleApp.Settings; @@ -23,7 +26,34 @@ // block, uncomment the one you want, flip the matching ItemGroup in SampleApp.csproj, // the provider block in AppHost.cs, and the DatabaseProvider in AppDbContext.cs. // ───────────────────────────────────────────────────────────────────────────── -builder.AddNpgsqlDbContext("settingsdb"); +builder.Services.AddDbContext(opt => + opt.UseNpgsql( + builder.Configuration.GetConnectionString("settingsdb"), + // A cold Postgres container refuses a few connections before it accepts any, so + // retry transient failures instead of failing the first request after a restart. + // Bounded deliberately: the readiness probe below runs through this same strategy, + // and the default policy (6 retries backing off to 30s) makes it take about a + // minute to report a database that is plainly gone. + npgsql => npgsql.EnableRetryOnFailure( + maxRetryCount: 3, + maxRetryDelay: TimeSpan.FromSeconds(2), + errorCodesToAdd: null))); + +// The two registrations below come free with Aspire.Npgsql.EntityFrameworkCore.PostgreSQL +// and have to be written out when the plain provider is used, as it is here: +// readiness — without it /health answers Healthy while Postgres is unreachable, which +// makes it useless to anything that gates traffic on it. Nothing polls it +// today: add .WithHttpHealthCheck("/health") to the api resource in +// AppHost.cs to make WaitFor(api) wait on the database too. +// telemetry — Npgsql's ActivitySource and Meter, so a trace on the dashboard shows the +// SQL a request ran instead of stopping at the HTTP span, and the Metrics +// page carries the connection-pool counters. +builder.Services.AddHealthChecks() + .AddDbContextCheck(); + +builder.Services.AddOpenTelemetry() + .WithTracing(tracing => tracing.AddSource("Npgsql")) + .WithMetrics(metrics => metrics.AddMeter("Npgsql")); // ───────────────────────────────────────────────────────────────────────────── // Storage provider — ALTERNATIVE: SQL Server (Entity Framework Core) diff --git a/samples/SampleApp/SampleApp.csproj b/samples/SampleApp/SampleApp.csproj index 3f8cdff..b972e06 100644 --- a/samples/SampleApp/SampleApp.csproj +++ b/samples/SampleApp/SampleApp.csproj @@ -22,7 +22,8 @@ in Program.cs and the container started by aspire/DotNetBoost.Settings.AppHost. --> - + + diff --git a/tests/DotNetBoost.Settings.IntegrationTests/DotNetBoost.Settings.IntegrationTests.csproj b/tests/DotNetBoost.Settings.IntegrationTests/DotNetBoost.Settings.IntegrationTests.csproj index 919f0c9..6c93193 100644 --- a/tests/DotNetBoost.Settings.IntegrationTests/DotNetBoost.Settings.IntegrationTests.csproj +++ b/tests/DotNetBoost.Settings.IntegrationTests/DotNetBoost.Settings.IntegrationTests.csproj @@ -20,6 +20,5 @@ -