Clean up dead code, consolidate duplication, fix redundancies
Remove 9 dead methods, 6 unused constants, and redundant ReaderWriterLockSlim from MetadataCache. Consolidate repeated patterns into HasChapters, IsPlayable, and ToLowerString helpers. Extract shared API methods in SRFApiClient. Move variant manifest rewriting from controller to StreamProxyService. Make Auto quality distinct from HD. Update README architecture section.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using Jellyfin.Plugin.SRFPlay.Api.Models;
|
||||
using Jellyfin.Plugin.SRFPlay.Services.Interfaces;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -10,12 +9,10 @@ namespace Jellyfin.Plugin.SRFPlay.Services;
|
||||
/// <summary>
|
||||
/// Service for caching metadata from SRF API.
|
||||
/// </summary>
|
||||
public sealed class MetadataCache : IMetadataCache, IDisposable
|
||||
public sealed class MetadataCache : IMetadataCache
|
||||
{
|
||||
private readonly ILogger<MetadataCache> _logger;
|
||||
private readonly ConcurrentDictionary<string, CacheEntry<MediaComposition>> _mediaCompositionCache;
|
||||
private readonly ReaderWriterLockSlim _lock;
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MetadataCache"/> class.
|
||||
@@ -25,19 +22,6 @@ public sealed class MetadataCache : IMetadataCache, IDisposable
|
||||
{
|
||||
_logger = logger;
|
||||
_mediaCompositionCache = new ConcurrentDictionary<string, CacheEntry<MediaComposition>>();
|
||||
_lock = new ReaderWriterLockSlim();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
_lock?.Dispose();
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -53,30 +37,15 @@ public sealed class MetadataCache : IMetadataCache, IDisposable
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
if (_mediaCompositionCache.TryGetValue(urn, out var entry))
|
||||
{
|
||||
_lock.EnterReadLock();
|
||||
try
|
||||
if (entry.IsValid(cacheDurationMinutes))
|
||||
{
|
||||
if (_mediaCompositionCache.TryGetValue(urn, out var entry))
|
||||
{
|
||||
if (entry.IsValid(cacheDurationMinutes))
|
||||
{
|
||||
_logger.LogDebug("Cache hit for URN: {Urn}", urn);
|
||||
return entry.Value;
|
||||
}
|
||||
_logger.LogDebug("Cache hit for URN: {Urn}", urn);
|
||||
return entry.Value;
|
||||
}
|
||||
|
||||
_logger.LogDebug("Cache entry expired for URN: {Urn}", urn);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
return null;
|
||||
_logger.LogDebug("Cache entry expired for URN: {Urn}", urn);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -94,56 +63,9 @@ public sealed class MetadataCache : IMetadataCache, IDisposable
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
var entry = new CacheEntry<MediaComposition>(mediaComposition);
|
||||
_mediaCompositionCache.AddOrUpdate(urn, entry, (key, oldValue) => entry);
|
||||
_logger.LogDebug("Cached media composition for URN: {Urn}", urn);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// Cache is disposed, ignore
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes media composition from cache.
|
||||
/// </summary>
|
||||
/// <param name="urn">The URN.</param>
|
||||
public void RemoveMediaComposition(string urn)
|
||||
{
|
||||
if (string.IsNullOrEmpty(urn))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
if (_mediaCompositionCache.TryRemove(urn, out _))
|
||||
{
|
||||
_logger.LogDebug("Removed cached media composition for URN: {Urn}", urn);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// Cache is disposed, ignore
|
||||
}
|
||||
var entry = new CacheEntry<MediaComposition>(mediaComposition);
|
||||
_mediaCompositionCache.AddOrUpdate(urn, entry, (key, oldValue) => entry);
|
||||
_logger.LogDebug("Cached media composition for URN: {Urn}", urn);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -151,50 +73,8 @@ public sealed class MetadataCache : IMetadataCache, IDisposable
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
try
|
||||
{
|
||||
_lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
_mediaCompositionCache.Clear();
|
||||
_logger.LogInformation("Cleared metadata cache");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// Cache is disposed, ignore
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cache statistics.
|
||||
/// </summary>
|
||||
/// <returns>A tuple with cache count and size estimate.</returns>
|
||||
public (int Count, long SizeEstimate) GetStatistics()
|
||||
{
|
||||
try
|
||||
{
|
||||
_lock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
var count = _mediaCompositionCache.Count;
|
||||
// Rough estimate: average 50KB per entry
|
||||
var sizeEstimate = count * 50L * 1024;
|
||||
return (count, sizeEstimate);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
_mediaCompositionCache.Clear();
|
||||
_logger.LogInformation("Cleared metadata cache");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user