156 lines
6.4 KiB
C#
156 lines
6.4 KiB
C#
// -----------------------------------------------------------------------------
|
|
// IAdvisoryCacheService.cs
|
|
// Sprint: SPRINT_8200_0013_0001_GW_valkey_advisory_cache
|
|
// Task: VCACHE-8200-010
|
|
// Description: Interface for Valkey-based canonical advisory caching
|
|
// -----------------------------------------------------------------------------
|
|
|
|
using StellaOps.Concelier.Core.Canonical;
|
|
|
|
namespace StellaOps.Concelier.Cache.Valkey;
|
|
|
|
/// <summary>
|
|
/// Valkey-based cache for canonical advisories.
|
|
/// Provides read-through caching with TTL based on interest score.
|
|
/// </summary>
|
|
public interface IAdvisoryCacheService
|
|
{
|
|
// === Read Operations ===
|
|
|
|
/// <summary>
|
|
/// Get canonical advisory by merge hash (cache-first).
|
|
/// </summary>
|
|
/// <param name="mergeHash">The merge hash identifying the canonical.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>The cached advisory, or null if not found.</returns>
|
|
Task<CanonicalAdvisory?> GetAsync(string mergeHash, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Get canonical advisories by PURL (uses index).
|
|
/// </summary>
|
|
/// <param name="purl">The PURL to lookup.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>List of advisories affecting this PURL.</returns>
|
|
Task<IReadOnlyList<CanonicalAdvisory>> GetByPurlAsync(string purl, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Get canonical advisory by CVE (uses mapping).
|
|
/// </summary>
|
|
/// <param name="cve">The CVE identifier.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>The primary canonical for this CVE, or null.</returns>
|
|
Task<CanonicalAdvisory?> GetByCveAsync(string cve, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Get hot advisories (top N by interest score).
|
|
/// </summary>
|
|
/// <param name="limit">Maximum number to return.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>List of hot advisories in descending score order.</returns>
|
|
Task<IReadOnlyList<CanonicalAdvisory>> GetHotAsync(int limit = 100, CancellationToken cancellationToken = default);
|
|
|
|
// === Write Operations ===
|
|
|
|
/// <summary>
|
|
/// Cache canonical advisory with TTL based on interest score.
|
|
/// </summary>
|
|
/// <param name="advisory">The advisory to cache.</param>
|
|
/// <param name="interestScore">Optional interest score (0.0-1.0) for TTL calculation.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
Task SetAsync(CanonicalAdvisory advisory, double? interestScore = null, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Invalidate cached advisory.
|
|
/// </summary>
|
|
/// <param name="mergeHash">The merge hash to invalidate.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
Task InvalidateAsync(string mergeHash, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Update interest score (affects TTL and hot set membership).
|
|
/// </summary>
|
|
/// <param name="mergeHash">The merge hash to update.</param>
|
|
/// <param name="score">The new interest score (0.0-1.0).</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
Task UpdateScoreAsync(string mergeHash, double score, CancellationToken cancellationToken = default);
|
|
|
|
// === Index Operations ===
|
|
|
|
/// <summary>
|
|
/// Add merge hash to PURL index.
|
|
/// </summary>
|
|
/// <param name="purl">The PURL to index.</param>
|
|
/// <param name="mergeHash">The merge hash to add.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
Task IndexPurlAsync(string purl, string mergeHash, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Remove merge hash from PURL index.
|
|
/// </summary>
|
|
/// <param name="purl">The PURL to unindex.</param>
|
|
/// <param name="mergeHash">The merge hash to remove.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
Task UnindexPurlAsync(string purl, string mergeHash, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Set CVE to merge hash mapping.
|
|
/// </summary>
|
|
/// <param name="cve">The CVE identifier.</param>
|
|
/// <param name="mergeHash">The canonical merge hash.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
Task IndexCveAsync(string cve, string mergeHash, CancellationToken cancellationToken = default);
|
|
|
|
// === Maintenance ===
|
|
|
|
/// <summary>
|
|
/// Warm cache with hot advisories from database.
|
|
/// </summary>
|
|
/// <param name="limit">Maximum number of advisories to preload.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
Task WarmupAsync(int limit = 1000, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Get cache statistics.
|
|
/// </summary>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>Current cache statistics.</returns>
|
|
Task<CacheStatistics> GetStatisticsAsync(CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Check if the cache service is healthy.
|
|
/// </summary>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>True if the cache is reachable and operational.</returns>
|
|
Task<bool> IsHealthyAsync(CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cache statistics for monitoring and debugging.
|
|
/// </summary>
|
|
public sealed record CacheStatistics
|
|
{
|
|
/// <summary>Total cache hits.</summary>
|
|
public long Hits { get; init; }
|
|
|
|
/// <summary>Total cache misses.</summary>
|
|
public long Misses { get; init; }
|
|
|
|
/// <summary>Cache hit rate (0.0-1.0).</summary>
|
|
public double HitRate => Hits + Misses > 0 ? (double)Hits / (Hits + Misses) : 0;
|
|
|
|
/// <summary>Current size of the hot advisory set.</summary>
|
|
public long HotSetSize { get; init; }
|
|
|
|
/// <summary>Approximate total cached advisories.</summary>
|
|
public long TotalCachedAdvisories { get; init; }
|
|
|
|
/// <summary>When the cache was last warmed up.</summary>
|
|
public DateTimeOffset? LastWarmup { get; init; }
|
|
|
|
/// <summary>Whether the cache service is currently healthy.</summary>
|
|
public bool IsHealthy { get; init; }
|
|
|
|
/// <summary>Valkey server info string.</summary>
|
|
public string? ServerInfo { get; init; }
|
|
}
|