From 11bb3951d2a994cc11366334809406233dbf003e Mon Sep 17 00:00:00 2001 From: Erik Darling <2136037+erikdarlingdata@users.noreply.github.com> Date: Sun, 27 Sep 2026 14:38:14 -0400 Subject: [PATCH] Clear two analyzer warnings on dev CA1068 in DarlingAgReader.GetAgHealthAsync (limit was after the CancellationToken; moved before it and updated callers to name the token). CA2249 in FactAdvice.IsVowel (IndexOf(c) >= 0 replaced with Contains(c)). No behavior change. --- .../Darling.Tests/AvailabilityGroupCountReadTests.cs | 4 ++-- .../DarlingAgStatesReaderLiveEqualityTests.cs | 4 ++-- Darling/Darling.Tests/DarlingMcpAgToolsTests.cs | 12 ++++++------ .../DarlingWebEndpoints.cs | 2 +- .../Mcp/DarlingAgReader.cs | 4 ++-- PerformanceMonitor.Analysis/FactAdvice.cs | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Darling/Darling.Tests/AvailabilityGroupCountReadTests.cs b/Darling/Darling.Tests/AvailabilityGroupCountReadTests.cs index 2a1d411bf5..8a03cadcb8 100644 --- a/Darling/Darling.Tests/AvailabilityGroupCountReadTests.cs +++ b/Darling/Darling.Tests/AvailabilityGroupCountReadTests.cs @@ -63,13 +63,13 @@ await DarlingMcpTestData.ExecAsync(connection, ct, } var unfilteredCount = await DarlingAgReader.GetAvailabilityGroupCountAsync(postgres, null, ct); - var unfilteredTopology = await DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, ct); + var unfilteredTopology = await DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, cancellationToken: ct); Assert.Equal(2, unfilteredCount); Assert.Equal(unfilteredTopology.AvailabilityGroupCount, unfilteredCount); // $1 binds the same way on both reads (the server-filtered path /api/read/get_ag_health takes). var filteredCount = await DarlingAgReader.GetAvailabilityGroupCountAsync(postgres, ServerId, ct); - var filteredTopology = await DarlingAgReader.GetAgHealthAsync(postgres, ServerId, DateTime.UtcNow, ct); + var filteredTopology = await DarlingAgReader.GetAgHealthAsync(postgres, ServerId, DateTime.UtcNow, cancellationToken: ct); Assert.Equal(2, filteredCount); Assert.Equal(filteredTopology.AvailabilityGroupCount, filteredCount); diff --git a/Darling/Darling.Tests/DarlingAgStatesReaderLiveEqualityTests.cs b/Darling/Darling.Tests/DarlingAgStatesReaderLiveEqualityTests.cs index 93adadba9a..9dbfcbd680 100644 --- a/Darling/Darling.Tests/DarlingAgStatesReaderLiveEqualityTests.cs +++ b/Darling/Darling.Tests/DarlingAgStatesReaderLiveEqualityTests.cs @@ -262,7 +262,7 @@ the output-side is_enabled join excludes it exactly as today. */ Assert.Equal(2, removedCard.Databases.Count); } - var fleetHealth = await DarlingAgReader.GetAgHealthAsync(postgres, null, now, ct); + var fleetHealth = await DarlingAgReader.GetAgHealthAsync(postgres, null, now, cancellationToken: ct); var fleetGroups = fleetHealth.AvailabilityGroups.Where(g => sentinelIds.Contains(g.ServerId)).ToList(); Assert.Equal(9, fleetGroups.Count); Assert.DoesNotContain(fleetGroups, g => g.ServerId == disabledId); @@ -270,7 +270,7 @@ the output-side is_enabled join excludes it exactly as today. */ var fleetCount = await DarlingAgReader.GetAvailabilityGroupCountAsync(postgres, null, ct); Assert.Equal(fleetHealth.AvailabilityGroupCount, fleetCount); - var scopedHealth = await DarlingAgReader.GetAgHealthAsync(postgres, staleId, now, ct); + var scopedHealth = await DarlingAgReader.GetAgHealthAsync(postgres, staleId, now, cancellationToken: ct); Assert.Equal(StaleName, Assert.Single(scopedHealth.AvailabilityGroups).ServerName); var fleetJson = await DarlingMcpAgTools.GetAgHealth(postgres, null); diff --git a/Darling/Darling.Tests/DarlingMcpAgToolsTests.cs b/Darling/Darling.Tests/DarlingMcpAgToolsTests.cs index ed6b760e81..c05196b7ba 100644 --- a/Darling/Darling.Tests/DarlingMcpAgToolsTests.cs +++ b/Darling/Darling.Tests/DarlingMcpAgToolsTests.cs @@ -292,7 +292,7 @@ await DarlingMcpTestData.ExecAsync(connection, ct, "ONLINE", "CONNECTED", "ONLINE", "HEALTHY", "SYNCHRONOUS_COMMIT", "AUTOMATIC", "TCP://AGNODE1:5022"); /* Straight through the reader, exactly as the /api/ag endpoint calls it — no server filter. */ - var result = await DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, ct); + var result = await DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, cancellationToken: ct); var group = Assert.Single(result.AvailabilityGroups, g => g.ServerName == ServerName); Assert.Equal("AG_FLEET", group.AgName); @@ -340,7 +340,7 @@ public async Task AgHealth_ReturnsOnlyTheNewestSnapshot_AgainstDevPostgres() /* Newest sweep: one replica, healthy. */ await InsertReplicaAsync(connection, ct, newest, "AG_SNAP", "NEW1", "PRIMARY", "HEALTHY"); - var result = await DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, ct); + var result = await DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, cancellationToken: ct); var group = Assert.Single(result.AvailabilityGroups, g => g.ServerName == ServerName); Assert.Equal(newest, group.CollectionTime); @@ -386,10 +386,10 @@ the unfiltered one. */ await InsertReplicaAsync(connection, ct, when, "AG_MINE", "MINE1", "PRIMARY", "HEALTHY"); await InsertReplicaAsync(connection, ct, when, "AG_THEIRS", "THEIRS1", "PRIMARY", "HEALTHY", otherId, OtherName); - var filtered = await DarlingAgReader.GetAgHealthAsync(postgres, ServerId, DateTime.UtcNow, ct); + var filtered = await DarlingAgReader.GetAgHealthAsync(postgres, ServerId, DateTime.UtcNow, cancellationToken: ct); Assert.Equal("AG_MINE", Assert.Single(filtered.AvailabilityGroups).AgName); - var unfiltered = await DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, ct); + var unfiltered = await DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, cancellationToken: ct); var names = unfiltered.AvailabilityGroups.Select(g => g.AgName).ToList(); Assert.Contains("AG_MINE", names); Assert.Contains("AG_THEIRS", names); @@ -428,13 +428,13 @@ go with it rather than linger until retention expires the collected rows. */ var when = DarlingMcpTestData.TruncateToSeconds(DateTime.UtcNow).AddMinutes(-5); await InsertReplicaAsync(connection, ct, when, "AG_DISABLED", "NODE1", "PRIMARY", "HEALTHY"); - var before = await DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, ct); + var before = await DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, cancellationToken: ct); Assert.Contains("AG_DISABLED", before.AvailabilityGroups.Select(g => g.AgName)); await DarlingMcpTestData.ExecAsync(connection, ct, "UPDATE servers SET is_enabled = FALSE WHERE server_id = $1", ServerId); - var after = await DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, ct); + var after = await DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, cancellationToken: ct); Assert.DoesNotContain("AG_DISABLED", after.AvailabilityGroups.Select(g => g.AgName)); bodySucceeded = true; diff --git a/Darling/PerformanceMonitor.Darling.Service/DarlingWebEndpoints.cs b/Darling/PerformanceMonitor.Darling.Service/DarlingWebEndpoints.cs index 3b3273b4ca..3ffdfc8717 100644 --- a/Darling/PerformanceMonitor.Darling.Service/DarlingWebEndpoints.cs +++ b/Darling/PerformanceMonitor.Darling.Service/DarlingWebEndpoints.cs @@ -328,7 +328,7 @@ its own empty state and the nav gate can read the count off the same response. * app.MapGet("/api/ag", async (HttpContext context) => { var result = await DarlingAgReader.GetAgHealthAsync( - postgres, null, DateTime.UtcNow, context.RequestAborted); + postgres, null, DateTime.UtcNow, cancellationToken: context.RequestAborted); return Results.Json(result, DarlingAgReader.JsonOptions); }); diff --git a/Darling/PerformanceMonitor.Darling.Service/Mcp/DarlingAgReader.cs b/Darling/PerformanceMonitor.Darling.Service/Mcp/DarlingAgReader.cs index 632ffdf1ea..29fe53d69f 100644 --- a/Darling/PerformanceMonitor.Darling.Service/Mcp/DarlingAgReader.cs +++ b/Darling/PerformanceMonitor.Darling.Service/Mcp/DarlingAgReader.cs @@ -87,8 +87,8 @@ public static async Task GetAgHealthAsync( NpgsqlDataSource postgres, int? serverIdFilter = null, DateTime? nowUtc = null, - CancellationToken cancellationToken = default, - int? limit = null) + int? limit = null, + CancellationToken cancellationToken = default) { var effectiveNow = nowUtc ?? DateTime.UtcNow; var replicas = await ReadReplicasAsync(postgres, serverIdFilter, effectiveNow, cancellationToken); diff --git a/PerformanceMonitor.Analysis/FactAdvice.cs b/PerformanceMonitor.Analysis/FactAdvice.cs index 89ca46e300..e99f076c67 100644 --- a/PerformanceMonitor.Analysis/FactAdvice.cs +++ b/PerformanceMonitor.Analysis/FactAdvice.cs @@ -992,7 +992,7 @@ private static string PluralNoun(string noun, bool isSingular) return noun + "s"; } - private static bool IsVowel(char c) => "aeiouAEIOU".IndexOf(c) >= 0; + private static bool IsVowel(char c) => "aeiouAEIOU".Contains(c); // Anomaly value formatters (passed to ComposeAnomaly as the observed/baseline renderer). private static string Pct(double v) => $"{v:0.#}%";