Files
XplorePlane/XplorePlane/Services/Matrix/MatrixSummaryWriter.cs
T

94 lines
4.0 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using XP.Common.Logging.Interfaces;
using XplorePlane.Models;
namespace XplorePlane.Services.Matrix
{
/// <summary>
/// 矩阵执行摘要写入器,负责将矩阵执行结果序列化为 matrix_summary.json 文件。
/// Matrix execution summary writer, responsible for serializing matrix execution results to matrix_summary.json.
/// </summary>
public class MatrixSummaryWriter
{
private readonly ILoggerService _logger;
private static readonly JsonSerializerOptions SummaryJsonOptions = new()
{
WriteIndented = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters = { new JsonStringEnumConverter() }
};
public MatrixSummaryWriter(ILoggerService logger)
{
ArgumentNullException.ThrowIfNull(logger);
_logger = logger.ForModule<MatrixSummaryWriter>();
}
/// <summary>
/// 将矩阵执行摘要写入 JSON 文件。写入失败时记录错误日志,不重新抛出异常。
/// Write matrix execution summary to JSON file. Logs error on failure without rethrowing.
/// </summary>
/// <param name="layout">矩阵布局 | Matrix layout</param>
/// <param name="templateProgramName">模板程序名称 | Template program name</param>
/// <param name="startTime">执行开始时间 | Execution start time</param>
/// <param name="cellEntries">各单元格摘要条目 | Cell summary entries</param>
/// <param name="outputDirectory">输出目录 | Output directory</param>
/// <param name="ct">取消令牌 | Cancellation token</param>
public async Task WriteAsync(
MatrixLayout layout,
string templateProgramName,
DateTime startTime,
IReadOnlyList<MatrixCellSummaryEntry> cellEntries,
string outputDirectory,
CancellationToken ct = default)
{
try
{
var duration = DateTime.UtcNow - startTime;
var summaryFile = new MatrixSummaryFile
{
Config = new MatrixSummaryConfig
{
Rows = layout.Rows,
Columns = layout.Columns,
RowSpacing = layout.RowSpacing,
ColumnSpacing = layout.ColumnSpacing
},
ProgramName = templateProgramName,
StartTime = startTime.ToString("o"),
DurationSeconds = Math.Round(duration.TotalSeconds, 2),
TotalCells = layout.Rows * layout.Columns,
EnabledCells = layout.Cells.Count(c => c.IsEnabled),
CompletedCells = cellEntries.Count(e => e.Status == nameof(MatrixCellStatus.Completed)),
FailedCells = cellEntries.Count(e => e.Status == nameof(MatrixCellStatus.Error)),
Cells = cellEntries.ToList()
};
var json = JsonSerializer.Serialize(summaryFile, SummaryJsonOptions);
var filePath = Path.Combine(outputDirectory, "matrix_summary.json");
Directory.CreateDirectory(outputDirectory);
await File.WriteAllTextAsync(filePath, json, ct).ConfigureAwait(false);
_logger.Info("已写入矩阵执行摘要 | Matrix summary written: {FilePath}", filePath);
}
catch (Exception ex)
{
_logger.Error(ex, "写入矩阵执行摘要失败 | Failed to write matrix summary to {OutputDirectory}", outputDirectory);
// 不重新抛出,确保不影响已完成的单元格检测结果归档
}
}
}
}