fix: preserve endurance failures and validate milestone reports

This commit is contained in:
2026-09-05 22:55:56 +08:00
parent 1e8e894dba
commit e0d1ea1022
3 changed files with 110 additions and 20 deletions
+24 -3
View File
@@ -60,8 +60,8 @@ public static class WechatStabilityAnalyzer
if (memoryGrowth > 256L * 1024 * 1024) findings.Add("working-set-growth-over-256mb");
if (handleGrowth > 500) findings.Add("handle-growth-over-500");
if (threadGrowth > 100) findings.Add("thread-growth-over-100");
if (samples.Any(sample => sample.LastSnapshotAt is { } lastSnapshot
&& sample.Timestamp - lastSnapshot > TimeSpan.FromMinutes(5))) findings.Add("listener-snapshot-gap-over-5min");
if (samples.Any(sample => sample.Timestamp - (sample.LastSnapshotAt ?? startedAt) > TimeSpan.FromMinutes(5)))
findings.Add("listener-snapshot-gap-over-5min");
return new WechatStabilityReport(
startedAt,
@@ -76,10 +76,31 @@ public static class WechatStabilityAnalyzer
findings);
}
public static WechatStabilityReport CheckRun(
WechatStabilityReport report, TimeSpan requested, TimeSpan observed, bool cancelled,
string? listenerFailure = null, string? samplingFailure = null)
{
var findings = report.Findings.ToList();
var completed = observed + TimeSpan.FromSeconds(1) >= requested && !cancelled;
if (!completed) findings.Add("duration-incomplete");
if (listenerFailure is not null) findings.Add("listener-failed:" + listenerFailure);
if (samplingFailure is not null) findings.Add("sampling-failed:" + samplingFailure);
if (report.Samples[^1].LastSnapshotAt is not { } snapshot
|| report.FinishedAt - snapshot > TimeSpan.FromSeconds(10)) findings.Add("listener-snapshot-stale");
return report with { Healthy = findings.Count == 0, Findings = findings, RequestedSeconds = requested.TotalSeconds,
ObservedSeconds = observed.TotalSeconds, CompletedDuration = completed };
}
public static async Task WriteJsonAsync(WechatStabilityReport report, string path, CancellationToken cancellationToken)
{
var fullPath = Path.GetFullPath(path);
Directory.CreateDirectory(Path.GetDirectoryName(fullPath)!);
await File.WriteAllTextAsync(fullPath, JsonSerializer.Serialize(report, new JsonSerializerOptions { WriteIndented = true }), cancellationToken);
var temporary = fullPath + ".tmp";
try
{
await File.WriteAllTextAsync(temporary, JsonSerializer.Serialize(report, new JsonSerializerOptions { WriteIndented = true }), cancellationToken);
File.Move(temporary, fullPath, overwrite: true);
}
finally { if (File.Exists(temporary)) File.Delete(temporary); }
}
}