From 5667c2e12fd13cbdd28f573ed3c2640fca04f507 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sat, 27 Jun 2026 09:34:07 +0200 Subject: [PATCH] Cache manageent for bussines units --- .../Services/CategoryService.cs | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/Jellyfin.Plugin.SRFPlay/Services/CategoryService.cs b/Jellyfin.Plugin.SRFPlay/Services/CategoryService.cs index 81c8c2a..94b2f83 100644 --- a/Jellyfin.Plugin.SRFPlay/Services/CategoryService.cs +++ b/Jellyfin.Plugin.SRFPlay/Services/CategoryService.cs @@ -18,8 +18,10 @@ public class CategoryService : ICategoryService private readonly ILogger _logger; private readonly ISRFApiClientFactory _apiClientFactory; private readonly TimeSpan _topicsCacheDuration = TimeSpan.FromHours(24); - private Dictionary? _topicsCache; - private DateTime _topicsCacheExpiry = DateTime.MinValue; + + // Cache topics per business unit. A single shared cache would return one unit's + // topics (e.g. German SRF) even after the user switched to another (e.g. French RTS). + private readonly Dictionary Topics, DateTime Expiry)> _topicsCacheByUnit = new(StringComparer.OrdinalIgnoreCase); /// /// Initializes a new instance of the class. @@ -35,11 +37,11 @@ public class CategoryService : ICategoryService /// public async Task> GetTopicsAsync(string businessUnit, CancellationToken cancellationToken = default) { - // Return cached topics if still valid - if (_topicsCache != null && DateTime.UtcNow < _topicsCacheExpiry) + // Return cached topics for this business unit if still valid + if (_topicsCacheByUnit.TryGetValue(businessUnit, out var cached) && DateTime.UtcNow < cached.Expiry) { _logger.LogDebug("Returning cached topics for business unit: {BusinessUnit}", businessUnit); - return _topicsCache.Values.ToList(); + return cached.Topics.Values.ToList(); } _logger.LogInformation("Fetching topics for business unit: {BusinessUnit}", businessUnit); @@ -48,13 +50,13 @@ public class CategoryService : ICategoryService if (topics != null && topics.Count > 0) { - // Cache topics by ID for quick lookups - _topicsCache = topics + // Cache topics by ID for quick lookups, scoped to this business unit + var byId = topics .Where(t => !string.IsNullOrEmpty(t.Id)) .ToDictionary(t => t.Id!, t => t); - _topicsCacheExpiry = DateTime.UtcNow.Add(_topicsCacheDuration); + _topicsCacheByUnit[businessUnit] = (byId, DateTime.UtcNow.Add(_topicsCacheDuration)); - _logger.LogInformation("Cached {Count} topics for business unit: {BusinessUnit}", _topicsCache.Count, businessUnit); + _logger.LogInformation("Cached {Count} topics for business unit: {BusinessUnit}", byId.Count, businessUnit); } return topics ?? new List(); @@ -63,13 +65,14 @@ public class CategoryService : ICategoryService /// public async Task GetTopicByIdAsync(string topicId, string businessUnit, CancellationToken cancellationToken = default) { - // Ensure topics are loaded - if (_topicsCache == null || DateTime.UtcNow >= _topicsCacheExpiry) + // Ensure topics are loaded for this business unit + if (!_topicsCacheByUnit.TryGetValue(businessUnit, out var cached) || DateTime.UtcNow >= cached.Expiry) { await GetTopicsAsync(businessUnit, cancellationToken).ConfigureAwait(false); + _topicsCacheByUnit.TryGetValue(businessUnit, out cached); } - return _topicsCache?.GetValueOrDefault(topicId); + return cached.Topics?.GetValueOrDefault(topicId); } /// @@ -101,8 +104,7 @@ public class CategoryService : ICategoryService /// public void ClearCache() { - _topicsCache = null; - _topicsCacheExpiry = DateTime.MinValue; + _topicsCacheByUnit.Clear(); _logger.LogInformation("Topics cache cleared"); }