Import des bestehenden Projektstands in Git. - .NET 10 WinForms Anwendung (Multi-Agent / Tool-System) - .gitignore fuer Build-Artefakte, Secrets und Runtime-Daten ergaenzt Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
96 lines
2.5 KiB
C#
96 lines
2.5 KiB
C#
using System.Text.Json;
|
|
using ClawdDotNet.Models;
|
|
|
|
namespace ClawdDotNet.Services;
|
|
|
|
/// <summary>
|
|
/// Thread-safe JSON persistence for job execution history.
|
|
/// Uses file locking to handle concurrent access from multiple schedulers.
|
|
/// </summary>
|
|
public sealed class JobHistoryService
|
|
{
|
|
private readonly string _filePath;
|
|
private readonly Lock _lock = new();
|
|
private readonly int _maxEntries;
|
|
private List<JobHistoryEntry> _entries = new();
|
|
|
|
private static readonly JsonSerializerOptions JsonOptions = new()
|
|
{
|
|
WriteIndented = true
|
|
};
|
|
|
|
public JobHistoryService(string instancePath, int maxEntries = 500)
|
|
{
|
|
_filePath = Path.Combine(instancePath, "job_history.json");
|
|
_maxEntries = maxEntries;
|
|
Load();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a new entry to the history (thread-safe, persists immediately).
|
|
/// </summary>
|
|
public void Add(JobHistoryEntry entry)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
_entries.Insert(0, entry); // newest first
|
|
|
|
// Trim old entries
|
|
if (_entries.Count > _maxEntries)
|
|
_entries = _entries.Take(_maxEntries).ToList();
|
|
|
|
Save();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a snapshot of all entries (newest first).
|
|
/// </summary>
|
|
public List<JobHistoryEntry> GetAll()
|
|
{
|
|
lock (_lock)
|
|
return new List<JobHistoryEntry>(_entries);
|
|
}
|
|
|
|
private void Load()
|
|
{
|
|
lock (_lock)
|
|
{
|
|
try
|
|
{
|
|
if (!File.Exists(_filePath))
|
|
{
|
|
_entries = new List<JobHistoryEntry>();
|
|
return;
|
|
}
|
|
|
|
using var stream = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
_entries = JsonSerializer.Deserialize<List<JobHistoryEntry>>(stream, JsonOptions)
|
|
?? new List<JobHistoryEntry>();
|
|
}
|
|
catch
|
|
{
|
|
_entries = new List<JobHistoryEntry>();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Save()
|
|
{
|
|
try
|
|
{
|
|
var tmpPath = _filePath + ".tmp";
|
|
using (var stream = new FileStream(tmpPath, FileMode.Create, FileAccess.Write, FileShare.None))
|
|
{
|
|
JsonSerializer.Serialize(stream, _entries, JsonOptions);
|
|
}
|
|
|
|
File.Move(tmpPath, _filePath, overwrite: true);
|
|
}
|
|
catch
|
|
{
|
|
// Silently ignore write failures — next save will retry
|
|
}
|
|
}
|
|
}
|