Fix bug where stale cache causes media player to mix up episode names
This commit is contained in:
parent
221a3f634d
commit
c54221fba2
@ -387,10 +387,9 @@ public class JellypodChannel : IChannel, IHasCacheKey, IRequiresMediaInfoCallbac
|
||||
/// <inheritdoc />
|
||||
public string? GetCacheKey(string? userId)
|
||||
{
|
||||
// Use 5-minute time buckets for cache key
|
||||
var now = DateTime.Now;
|
||||
var timeBucket = new DateTime(now.Year, now.Month, now.Day, now.Hour, (now.Minute / 5) * 5, 0);
|
||||
return timeBucket.ToString("yyyy-MM-dd-HH-mm", CultureInfo.InvariantCulture);
|
||||
// Include database modification time so cache invalidates when podcasts/episodes change
|
||||
var lastModified = _storageService.LastModified;
|
||||
return lastModified.ToString("O", CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@ -10,6 +10,12 @@ namespace Jellyfin.Plugin.Jellypod.Services;
|
||||
/// </summary>
|
||||
public interface IPodcastStorageService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the cached last modification time (synchronous, for cache key generation).
|
||||
/// Returns default if database hasn't been loaded yet.
|
||||
/// </summary>
|
||||
DateTime LastModified { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets all subscribed podcasts.
|
||||
/// </summary>
|
||||
@ -57,4 +63,10 @@ public interface IPodcastStorageService
|
||||
/// </summary>
|
||||
/// <returns>The base path for podcast storage.</returns>
|
||||
string GetStoragePath();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last time the database was modified.
|
||||
/// </summary>
|
||||
/// <returns>The last modification time, or null if unknown.</returns>
|
||||
Task<DateTime?> GetLastModifiedAsync();
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
|
||||
private readonly IApplicationPaths _applicationPaths;
|
||||
private readonly SemaphoreSlim _dbLock = new(1, 1);
|
||||
private PodcastDatabase? _cache;
|
||||
private DateTime _lastModified;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PodcastStorageService"/> class.
|
||||
@ -47,6 +48,9 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
|
||||
"Jellypod",
|
||||
"podcasts.json");
|
||||
|
||||
/// <inheritdoc />
|
||||
public DateTime LastModified => _lastModified;
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<Podcast>> GetAllPodcastsAsync()
|
||||
{
|
||||
@ -180,6 +184,7 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
|
||||
{
|
||||
_logger.LogWarning("Database file does not exist at {Path}", DatabasePath);
|
||||
_cache = new PodcastDatabase();
|
||||
_lastModified = DateTime.UtcNow;
|
||||
return _cache;
|
||||
}
|
||||
|
||||
@ -189,6 +194,7 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
|
||||
var json = await File.ReadAllTextAsync(DatabasePath).ConfigureAwait(false);
|
||||
_logger.LogInformation("Read {Length} characters from database file", json.Length);
|
||||
_cache = JsonSerializer.Deserialize<PodcastDatabase>(json, JsonOptions) ?? new PodcastDatabase();
|
||||
_lastModified = _cache.LastSaved;
|
||||
_logger.LogInformation("Loaded {Count} podcasts from database", _cache.Podcasts.Count);
|
||||
return _cache;
|
||||
}
|
||||
@ -196,6 +202,7 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
|
||||
{
|
||||
_logger.LogError(ex, "Failed to load podcast database, starting fresh");
|
||||
_cache = new PodcastDatabase();
|
||||
_lastModified = DateTime.UtcNow;
|
||||
return _cache;
|
||||
}
|
||||
}
|
||||
@ -211,6 +218,7 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
|
||||
}
|
||||
|
||||
db.LastSaved = DateTime.UtcNow;
|
||||
_lastModified = db.LastSaved;
|
||||
var json = JsonSerializer.Serialize(db, JsonOptions);
|
||||
await File.WriteAllTextAsync(DatabasePath, json).ConfigureAwait(false);
|
||||
_cache = db;
|
||||
@ -261,6 +269,13 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
|
||||
return ".mp3";
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<DateTime?> GetLastModifiedAsync()
|
||||
{
|
||||
var db = await LoadDatabaseAsync().ConfigureAwait(false);
|
||||
return db.LastSaved;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user