mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-02 06:46:31 +01:00
Implement limiting caches (#13605)
* Implement basic expiring cache for LibraryManager * Add expiring cache to more places * Rider why * Make DirectoryService caches static * Use FastConcurrentLru * Reduce default cache size * Simplify DirectoryService caches * Make directory service cache size at least 128
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BitFaster.Caching" />
|
||||
<PackageReference Include="DiscUtils.Udf" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#pragma warning disable CA5394
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
@@ -11,6 +10,7 @@ using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BitFaster.Caching.Lru;
|
||||
using Emby.Naming.Common;
|
||||
using Emby.Naming.TV;
|
||||
using Emby.Server.Implementations.Library.Resolvers;
|
||||
@@ -64,7 +64,6 @@ namespace Emby.Server.Implementations.Library
|
||||
private const string ShortcutFileExtension = ".mblink";
|
||||
|
||||
private readonly ILogger<LibraryManager> _logger;
|
||||
private readonly ConcurrentDictionary<Guid, BaseItem> _cache;
|
||||
private readonly ITaskManager _taskManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataRepository;
|
||||
@@ -81,6 +80,7 @@ namespace Emby.Server.Implementations.Library
|
||||
private readonly IPeopleRepository _peopleRepository;
|
||||
private readonly ExtraResolver _extraResolver;
|
||||
private readonly IPathManager _pathManager;
|
||||
private readonly FastConcurrentLru<Guid, BaseItem> _cache;
|
||||
|
||||
/// <summary>
|
||||
/// The _root folder sync lock.
|
||||
@@ -150,7 +150,9 @@ namespace Emby.Server.Implementations.Library
|
||||
_mediaEncoder = mediaEncoder;
|
||||
_itemRepository = itemRepository;
|
||||
_imageProcessor = imageProcessor;
|
||||
_cache = new ConcurrentDictionary<Guid, BaseItem>();
|
||||
|
||||
_cache = new FastConcurrentLru<Guid, BaseItem>(_configurationManager.Configuration.CacheSize);
|
||||
|
||||
_namingOptions = namingOptions;
|
||||
_peopleRepository = peopleRepository;
|
||||
_pathManager = pathManager;
|
||||
@@ -158,7 +160,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
_configurationManager.ConfigurationUpdated += ConfigurationUpdated;
|
||||
|
||||
RecordConfigurationValues(configurationManager.Configuration);
|
||||
RecordConfigurationValues(_configurationManager.Configuration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -306,7 +308,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
}
|
||||
|
||||
_cache[item.Id] = item;
|
||||
_cache.AddOrUpdate(item.Id, item);
|
||||
}
|
||||
|
||||
public void DeleteItem(BaseItem item, DeleteOptions options)
|
||||
@@ -460,14 +462,13 @@ namespace Emby.Server.Implementations.Library
|
||||
item.SetParent(null);
|
||||
|
||||
_itemRepository.DeleteItem(item.Id);
|
||||
_cache.TryRemove(item.Id, out _);
|
||||
foreach (var child in children)
|
||||
{
|
||||
_itemRepository.DeleteItem(child.Id);
|
||||
_cache.TryRemove(child.Id, out _);
|
||||
}
|
||||
|
||||
_cache.TryRemove(item.Id, out _);
|
||||
|
||||
ReportItemRemoved(item, parent);
|
||||
}
|
||||
|
||||
@@ -1255,7 +1256,7 @@ namespace Emby.Server.Implementations.Library
|
||||
throw new ArgumentException("Guid can't be empty", nameof(id));
|
||||
}
|
||||
|
||||
if (_cache.TryGetValue(id, out BaseItem? item))
|
||||
if (_cache.TryGet(id, out var item))
|
||||
{
|
||||
return item;
|
||||
}
|
||||
@@ -1272,7 +1273,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
/// <inheritdoc />
|
||||
public T? GetItemById<T>(Guid id)
|
||||
where T : BaseItem
|
||||
where T : BaseItem
|
||||
{
|
||||
var item = GetItemById(id);
|
||||
if (item is T typedItem)
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
#pragma warning disable RS0030 // Do not use banned APIs
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using BitFaster.Caching.Lru;
|
||||
using Jellyfin.Database.Implementations;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
using Jellyfin.Extensions;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
@@ -26,11 +25,9 @@ namespace Emby.Server.Implementations.Library
|
||||
/// </summary>
|
||||
public class UserDataManager : IUserDataManager
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, UserItemData> _userData =
|
||||
new ConcurrentDictionary<string, UserItemData>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IDbContextFactory<JellyfinDbContext> _repository;
|
||||
private readonly FastConcurrentLru<string, UserItemData> _cache;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UserDataManager"/> class.
|
||||
@@ -43,6 +40,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
_config = config;
|
||||
_repository = repository;
|
||||
_cache = new FastConcurrentLru<string, UserItemData>(Environment.ProcessorCount, _config.Configuration.CacheSize, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -81,7 +79,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
var userId = user.InternalId;
|
||||
var cacheKey = GetCacheKey(userId, item.Id);
|
||||
_userData.AddOrUpdate(cacheKey, userData, (_, _) => userData);
|
||||
_cache.AddOrUpdate(cacheKey, userData);
|
||||
|
||||
UserDataSaved?.Invoke(this, new UserDataSaveEventArgs
|
||||
{
|
||||
@@ -182,7 +180,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
var cacheKey = GetCacheKey(user.InternalId, itemId);
|
||||
|
||||
if (_userData.TryGetValue(cacheKey, out var data))
|
||||
if (_cache.TryGet(cacheKey, out var data))
|
||||
{
|
||||
return data;
|
||||
}
|
||||
@@ -197,7 +195,7 @@ namespace Emby.Server.Implementations.Library
|
||||
};
|
||||
}
|
||||
|
||||
return _userData.GetOrAdd(cacheKey, data);
|
||||
return _cache.GetOrAdd(cacheKey, _ => data);
|
||||
}
|
||||
|
||||
private UserItemData? GetUserDataInternal(Guid userId, Guid itemId, List<string> keys)
|
||||
|
||||
Reference in New Issue
Block a user