Catalog/CatalogLite/ImageProcessingCoordinator.cs
Maddo 181229aa41
Some checks failed
Build Windows Avalonia / build (push) Failing after 1m43s
Build Windows Avalonia / release (push) Has been skipped
Catalog Lite
2026-05-26 21:47:55 +02:00

95 lines
No EOL
3.6 KiB
C#

using System.Collections.Concurrent;
using System.Diagnostics;
using MaddoShared;
using Microsoft.Extensions.Logging;
namespace CatalogLite;
public readonly record struct ImageProcessedUpdate(string Status, int Total, int Processed);
public sealed class ImageProcessingRunResult
{
public required string FinalSpeedCounter { get; init; }
}
public sealed class ImageProcessingCoordinator
{
private readonly ImageCreationService _imageCreationService;
private readonly ILogger<ImageProcessingCoordinator> _logger;
public ImageProcessingCoordinator(ImageCreationService imageCreationService, ILogger<ImageProcessingCoordinator> logger)
{
_imageCreationService = imageCreationService;
_logger = logger;
}
public async Task<ImageProcessingRunResult> RunAsync(
ImageCreationService.Options options,
CancellationToken token,
Action<ImageProcessedUpdate> onImageProcessed,
Action<string> onSpeedUpdated)
{
var results = new ConcurrentBag<string>();
var recentDiffs = new Queue<int>();
const int recentWindowSize = 5;
var currentAmount = 0;
var previousAmount = 0;
var processedAtomic = 0;
var speedWatch = Stopwatch.StartNew();
using var speedTimer = new System.Threading.Timer(_ =>
{
try
{
previousAmount = currentAmount;
currentAmount = Volatile.Read(ref processedAtomic);
var diff = Math.Max(0, currentAmount - previousAmount);
lock (recentDiffs)
{
recentDiffs.Enqueue(diff);
if (recentDiffs.Count > recentWindowSize)
{
recentDiffs.Dequeue();
}
}
double recentAverage;
lock (recentDiffs)
{
recentAverage = recentDiffs.Count == 0 ? 0.0 : recentDiffs.Average();
}
var total = Volatile.Read(ref processedAtomic);
var overall = speedWatch.Elapsed.TotalSeconds > 0 ? total / speedWatch.Elapsed.TotalSeconds : 0.0;
var elapsed = speedWatch.Elapsed;
var elapsedText = $"{(int)elapsed.TotalHours}h {elapsed.Minutes}m {elapsed.Seconds}s";
onSpeedUpdated($"{recentAverage:0.00} f/s (media: {overall:0.00} f/s) - {elapsedText}{Environment.NewLine}media: {recentAverage * 60.0:0.00} f/m");
}
catch (Exception ex)
{
_logger.LogDebug(ex, "Errore durante l'aggiornamento della velocita");
}
}, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
EventHandler<Tuple<string, int>> onImageProcessedInternal = (_, args) =>
{
var processed = Interlocked.Increment(ref processedAtomic);
onImageProcessed(new ImageProcessedUpdate(args.Item1, args.Item2, processed));
};
await _imageCreationService.CreaCatalogoParallel(options, results, onImageProcessedInternal, token).ConfigureAwait(false);
speedWatch.Stop();
var finalProcessed = Volatile.Read(ref processedAtomic);
var finalAverage = speedWatch.Elapsed.TotalSeconds > 0 ? finalProcessed / speedWatch.Elapsed.TotalSeconds : 0.0;
var finalElapsed = speedWatch.Elapsed;
return new ImageProcessingRunResult
{
FinalSpeedCounter = $"{(int)finalElapsed.TotalHours}h {finalElapsed.Minutes}m {finalElapsed.Seconds}s{Environment.NewLine}media: {finalAverage:0.00} f/s{Environment.NewLine}media: {finalAverage * 60.0:0.00} f/m"
};
}
}