123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- using InABox.Core;
- namespace InABox.Avalonia.Platform;
- public class StaleItemMonitor<T>
- {
- private readonly CoreObservableCollection<T> _items;
- private readonly Func<T, DateTime> _timestampSelector;
- private readonly Func<T, string> _displaySelector;
- private readonly TimeSpan _staleThreshold;
- private readonly TimeSpan _pollInterval;
- private CancellationTokenSource? _cts;
- private Task? _monitorTask;
- private readonly object _lock = new object();
-
- public event EventHandler? Changed;
- public StaleItemMonitor(
- CoreObservableCollection<T> items,
- Func<T, DateTime> timestampSelector,
- Func<T, String> displaySelector,
- TimeSpan staleThreshold,
- TimeSpan pollInterval)
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Initializing Stale Item monitor for {typeof(T).Name}");
- _items = items ?? throw new ArgumentNullException(nameof(items));
- _timestampSelector = timestampSelector ?? throw new ArgumentNullException(nameof(timestampSelector));
- _displaySelector = displaySelector ?? throw new ArgumentNullException(nameof(displaySelector));
- _staleThreshold = staleThreshold;
- _pollInterval = pollInterval;
- }
- public Task StartAsync()
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Starting Stale Item monitor for {typeof(T).Name}");
- if (_monitorTask != null && !_monitorTask.IsCompleted)
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Stale Item monitor already started");
- return Task.CompletedTask; // Already running
- }
- _cts = new CancellationTokenSource();
- _monitorTask = Task.Run(() => MonitorLoop(_cts.Token));
-
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Stale Item monitor started successfully");
- return Task.CompletedTask;
- }
- public async Task StopAsync()
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Stopping Stale Item monitor for {typeof(T).Name}");
- if (_monitorTask == null)
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Stale Item monitor already stopped");
- return;
- }
- if (_cts == null)
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Stale Item Monitor cancellation token is not set");
- return;
- }
-
- _cts.Cancel();
- try
- {
- await _monitorTask;
- }
- catch (OperationCanceledException)
- {
- // Expected during cancellation
- }
- finally
- {
- _cts.Dispose();
- _cts = null;
- _monitorTask = null;
- }
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Stale Item monitor stopped successfully");
-
- }
- private async Task MonitorLoop(CancellationToken token)
- {
- while (!token.IsCancellationRequested)
- {
- try
- {
- RemoveStaleItems();
- await Task.Delay(_pollInterval, token);
- }
- catch (OperationCanceledException)
- {
- // Cancellation requested, exit loop
- break;
- }
- catch (Exception ex)
- {
- // Log or handle other exceptions
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Monitor error: {ex.Message}");
- }
- }
- }
- private void RemoveStaleItems()
- {
- DateTime now = DateTime.UtcNow;
- lock (_lock)
- {
- var stale = _items.Where(item => (now - _timestampSelector(item)) > _staleThreshold).ToArray();
- if (stale.Any())
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Removing Stale Items {string.Join(", ", stale.Select(x=>_displaySelector(x)))}...");
- _items.RemoveAll(x => stale.Contains(x)); ;
- Changed?.Invoke(this, EventArgs.Empty);
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Removed {stale.Length} Stale Items.");
- }
- }
- }
- }
|