// File: Services/Scanners/AbstractScanner.cs using WebmrAPI.Utils; namespace WebmrAPI.Services.Scanners { public abstract class AbstractScanner : IScannable where T : new() { internal IScanProvider _provider; LazyConcurrentContainer _container; abstract public ScanTarget Target { get; } internal IScanProvider Provider { get => _provider; } internal LazyConcurrentContainer Container { get => _container; } internal int Timeout { get => _provider.GetTimeout(Target); } internal bool IsActual() { return (DateTime.UtcNow - Container.LastUpdate).TotalSeconds < Timeout; } internal bool GetFromCacheOrNew(long key, out T res) { var cache = Container.Container; bool result = true; T? found; if (cache == null || !cache.TryGetValue(key, out found)) { result = false; found = new(); } res = found; return result; } abstract internal Task ScanAsync(Dictionary data); public async Task ScanAsync() { bool success = false; if (Container.Container != null && IsActual()) return; try { Dictionary data = new(); if (success = await ScanAsync(data)) { Container.SetContainer(data); } } finally { if (!success) { Container.CleanContainer(); } } } public AbstractScanner(IScanProvider scanProvider, LazyConcurrentContainer container) { _provider = scanProvider; _container = container; } } }