From 3982b0e057cc692875ba35573197b86abf8d7adb Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Thu, 22 Jun 2023 05:01:47 +0200 Subject: Reduce bottlenecks scan code (#9863) --- .../BaseItemManager/BaseItemManager.cs | 65 +++------------------- .../BaseItemManager/IBaseItemManager.cs | 5 -- .../Entities/Audio/MusicArtist.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 33 +++-------- MediaBrowser.Controller/Entities/Folder.cs | 38 +++---------- .../Library/MetadataConfigurationExtensions.cs | 17 ++++-- .../Providers/IProviderManager.cs | 17 ------ 7 files changed, 37 insertions(+), 140 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs b/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs index ed7c2c2c17..b263c173eb 100644 --- a/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs +++ b/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs @@ -1,11 +1,10 @@ using System; -using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Threading; using Jellyfin.Extensions; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; using MediaBrowser.Model.Configuration; namespace MediaBrowser.Controller.BaseItemManager @@ -15,8 +14,6 @@ namespace MediaBrowser.Controller.BaseItemManager { private readonly IServerConfigurationManager _serverConfigurationManager; - private int _metadataRefreshConcurrency; - /// /// Initializes a new instance of the class. /// @@ -24,16 +21,8 @@ namespace MediaBrowser.Controller.BaseItemManager public BaseItemManager(IServerConfigurationManager serverConfigurationManager) { _serverConfigurationManager = serverConfigurationManager; - - _metadataRefreshConcurrency = GetMetadataRefreshConcurrency(); - SetupMetadataThrottler(); - - _serverConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated; } - /// - public SemaphoreSlim MetadataRefreshThrottler { get; private set; } - /// public bool IsMetadataFetcherEnabled(BaseItem baseItem, TypeOptions? libraryTypeOptions, string name) { @@ -51,12 +40,11 @@ namespace MediaBrowser.Controller.BaseItemManager if (libraryTypeOptions is not null) { - return libraryTypeOptions.MetadataFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase); + return libraryTypeOptions.MetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } - var itemConfig = _serverConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, baseItem.GetType().Name, StringComparison.OrdinalIgnoreCase)); - - return itemConfig is null || !itemConfig.DisabledMetadataFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase); + var itemConfig = _serverConfigurationManager.GetMetadataOptionsForType(baseItem.GetType().Name); + return itemConfig is null || !itemConfig.DisabledMetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } /// @@ -76,50 +64,11 @@ namespace MediaBrowser.Controller.BaseItemManager if (libraryTypeOptions is not null) { - return libraryTypeOptions.ImageFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase); - } - - var itemConfig = _serverConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, baseItem.GetType().Name, StringComparison.OrdinalIgnoreCase)); - - return itemConfig is null || !itemConfig.DisabledImageFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase); - } - - /// - /// Called when the configuration is updated. - /// It will refresh the metadata throttler if the relevant config changed. - /// - private void OnConfigurationUpdated(object? sender, EventArgs e) - { - int newMetadataRefreshConcurrency = GetMetadataRefreshConcurrency(); - if (_metadataRefreshConcurrency != newMetadataRefreshConcurrency) - { - _metadataRefreshConcurrency = newMetadataRefreshConcurrency; - SetupMetadataThrottler(); - } - } - - /// - /// Creates the metadata refresh throttler. - /// - [MemberNotNull(nameof(MetadataRefreshThrottler))] - private void SetupMetadataThrottler() - { - MetadataRefreshThrottler = new SemaphoreSlim(_metadataRefreshConcurrency); - } - - /// - /// Returns the metadata refresh concurrency. - /// - private int GetMetadataRefreshConcurrency() - { - var concurrency = _serverConfigurationManager.Configuration.LibraryMetadataRefreshConcurrency; - - if (concurrency <= 0) - { - concurrency = Environment.ProcessorCount; + return libraryTypeOptions.ImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } - return concurrency; + var itemConfig = _serverConfigurationManager.GetMetadataOptionsForType(baseItem.GetType().Name); + return itemConfig is null || !itemConfig.DisabledImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } } } diff --git a/MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs b/MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs index b07c80879d..ac20120d97 100644 --- a/MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs +++ b/MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs @@ -9,11 +9,6 @@ namespace MediaBrowser.Controller.BaseItemManager /// public interface IBaseItemManager { - /// - /// Gets the semaphore used to limit the amount of concurrent metadata refreshes. - /// - SemaphoreSlim MetadataRefreshThrottler { get; } - /// /// Is metadata fetcher enabled. /// diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 15a79fa1fc..18d948a62f 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -59,7 +59,7 @@ namespace MediaBrowser.Controller.Entities.Audio { if (IsAccessedByName) { - return new List(); + return Enumerable.Empty(); } return base.Children; diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 1e868194e6..5018110035 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1244,14 +1244,6 @@ namespace MediaBrowser.Controller.Entities return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken); } - protected virtual void TriggerOnRefreshStart() - { - } - - protected virtual void TriggerOnRefreshComplete() - { - } - /// /// Overrides the base implementation to refresh metadata for local trailers. /// @@ -1260,8 +1252,6 @@ namespace MediaBrowser.Controller.Entities /// true if a provider reports we changed. public async Task RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken) { - TriggerOnRefreshStart(); - var requiresSave = false; if (SupportsOwnedItems) @@ -1281,21 +1271,14 @@ namespace MediaBrowser.Controller.Entities } } - try - { - var refreshOptions = requiresSave - ? new MetadataRefreshOptions(options) - { - ForceSave = true - } - : options; + var refreshOptions = requiresSave + ? new MetadataRefreshOptions(options) + { + ForceSave = true + } + : options; - return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false); - } - finally - { - TriggerOnRefreshComplete(); - } + return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false); } protected bool IsVisibleStandaloneInternal(User user, bool checkFolders) @@ -1367,7 +1350,7 @@ namespace MediaBrowser.Controller.Entities private async Task RefreshExtras(BaseItem item, MetadataRefreshOptions options, IReadOnlyList fileSystemChildren, CancellationToken cancellationToken) { var extras = LibraryManager.FindExtras(item, fileSystemChildren, options.DirectoryService).ToArray(); - var newExtraIds = extras.Select(i => i.Id).ToArray(); + var newExtraIds = Array.ConvertAll(extras, x => x.Id); var extrasChanged = !item.ExtraIds.SequenceEqual(newExtraIds); if (!extrasChanged && !options.ReplaceAllMetadata && options.MetadataRefreshMode != MetadataRefreshMode.FullRefresh) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 84952295c4..44fe65103e 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -301,14 +301,6 @@ namespace MediaBrowser.Controller.Entities return dictionary; } - protected override void TriggerOnRefreshStart() - { - } - - protected override void TriggerOnRefreshComplete() - { - } - /// /// Validates the children internal. /// @@ -510,26 +502,17 @@ namespace MediaBrowser.Controller.Entities private async Task RefreshAllMetadataForContainer(IMetadataContainer container, MetadataRefreshOptions refreshOptions, IProgress progress, CancellationToken cancellationToken) { - // limit the amount of concurrent metadata refreshes - await ProviderManager.RunMetadataRefresh( - async () => - { - var series = container as Series; - if (series is not null) - { - await series.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); - } + if (container is Series series) + { + await series.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); + } - await container.RefreshAllMetadata(refreshOptions, progress, cancellationToken).ConfigureAwait(false); - }, - cancellationToken).ConfigureAwait(false); + await container.RefreshAllMetadata(refreshOptions, progress, cancellationToken).ConfigureAwait(false); } private async Task RefreshChildMetadata(BaseItem child, MetadataRefreshOptions refreshOptions, bool recursive, IProgress progress, CancellationToken cancellationToken) { - var container = child as IMetadataContainer; - - if (container is not null) + if (child is IMetadataContainer container) { await RefreshAllMetadataForContainer(container, refreshOptions, progress, cancellationToken).ConfigureAwait(false); } @@ -537,10 +520,7 @@ namespace MediaBrowser.Controller.Entities { if (refreshOptions.RefreshItem(child)) { - // limit the amount of concurrent metadata refreshes - await ProviderManager.RunMetadataRefresh( - async () => await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false), - cancellationToken).ConfigureAwait(false); + await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); } if (recursive && child is Folder folder) @@ -586,7 +566,7 @@ namespace MediaBrowser.Controller.Entities } var fanoutConcurrency = ConfigurationManager.Configuration.LibraryScanFanoutConcurrency; - var parallelism = fanoutConcurrency == 0 ? Environment.ProcessorCount : fanoutConcurrency; + var parallelism = fanoutConcurrency > 0 ? fanoutConcurrency : 2 * Environment.ProcessorCount; var actionBlock = new ActionBlock( async i => @@ -618,7 +598,7 @@ namespace MediaBrowser.Controller.Entities for (var i = 0; i < childrenCount; i++) { - actionBlock.Post(i); + await actionBlock.SendAsync(i).ConfigureAwait(false); } actionBlock.Complete(); diff --git a/MediaBrowser.Controller/Library/MetadataConfigurationExtensions.cs b/MediaBrowser.Controller/Library/MetadataConfigurationExtensions.cs index 41cfcae163..ee9420cb43 100644 --- a/MediaBrowser.Controller/Library/MetadataConfigurationExtensions.cs +++ b/MediaBrowser.Controller/Library/MetadataConfigurationExtensions.cs @@ -1,8 +1,8 @@ -#nullable disable - #pragma warning disable CS1591 +using System; using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Configuration; namespace MediaBrowser.Controller.Library @@ -10,8 +10,15 @@ namespace MediaBrowser.Controller.Library public static class MetadataConfigurationExtensions { public static MetadataConfiguration GetMetadataConfiguration(this IConfigurationManager config) - { - return config.GetConfiguration("metadata"); - } + => config.GetConfiguration("metadata"); + + /// + /// Gets the for the specified type. + /// + /// The . + /// The type to get the for. + /// The for the specified type or null. + public static MetadataOptions? GetMetadataOptionsForType(this IServerConfigurationManager config, string type) + => Array.Find(config.Configuration.MetadataOptions, i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)); } } diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index 7e0a69586c..16943f6aaa 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -54,14 +54,6 @@ namespace MediaBrowser.Controller.Providers /// Task. Task RefreshSingleItem(BaseItem item, MetadataRefreshOptions options, CancellationToken cancellationToken); - /// - /// Runs multiple metadata refreshes concurrently. - /// - /// The action to run. - /// The cancellation token. - /// A representing the result of the asynchronous operation. - Task RunMetadataRefresh(Func action, CancellationToken cancellationToken); - /// /// Saves the image. /// @@ -207,15 +199,6 @@ namespace MediaBrowser.Controller.Providers where TItemType : BaseItem, new() where TLookupType : ItemLookupInfo; - /// - /// Gets the search image. - /// - /// Name of the provider. - /// The URL. - /// The cancellation token. - /// Task{HttpResponseInfo}. - Task GetSearchImage(string providerName, string url, CancellationToken cancellationToken); - HashSet GetRefreshQueue(); void OnRefreshStart(BaseItem item); -- cgit v1.2.3