diff options
5 files changed, 54 insertions, 35 deletions
diff --git a/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs b/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs index 67aa7f338..0c8fa8244 100644 --- a/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs +++ b/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs @@ -1,5 +1,6 @@ -using System; +using System; using System.Linq; +using System.Threading; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -19,9 +20,23 @@ namespace MediaBrowser.Controller.BaseItemManager public BaseItemManager(IServerConfigurationManager serverConfigurationManager) { _serverConfigurationManager = serverConfigurationManager; + + MetadataRefreshThrottler = new Lazy<SemaphoreSlim>(() => { + var concurrency = _serverConfigurationManager.Configuration.LibraryMetadataRefreshConcurrency; + + if (concurrency <= 0) + { + concurrency = Environment.ProcessorCount; + } + + return new SemaphoreSlim(concurrency); + }); } /// <inheritdoc /> + public Lazy<SemaphoreSlim> MetadataRefreshThrottler { get; private set; } + + /// <inheritdoc /> public bool IsMetadataFetcherEnabled(BaseItem baseItem, LibraryOptions libraryOptions, string name) { if (baseItem is Channel) diff --git a/MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs b/MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs index ee4d3dcdc..d5f36dc2e 100644 --- a/MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs +++ b/MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Controller.Entities; +using System; +using System.Threading; +using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Configuration; namespace MediaBrowser.Controller.BaseItemManager @@ -9,6 +11,11 @@ namespace MediaBrowser.Controller.BaseItemManager public interface IBaseItemManager { /// <summary> + /// Gets the semaphore used to limit the amount of concurrent metadata refreshes. + /// </summary> + Lazy<SemaphoreSlim> MetadataRefreshThrottler { get; } + + /// <summary> /// Is metadata fetcher enabled. /// </summary> /// <param name="baseItem">The base item.</param> diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index e41407d7f..57d04ddfa 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -36,17 +36,6 @@ namespace MediaBrowser.Controller.Entities /// </summary> public class Folder : BaseItem { - private static Lazy<SemaphoreSlim> _metadataRefreshThrottler = new Lazy<SemaphoreSlim>(() => { - var concurrency = ConfigurationManager.Configuration.LibraryMetadataRefreshConcurrency; - - if (concurrency <= 0) - { - concurrency = Environment.ProcessorCount; - } - - return new SemaphoreSlim(concurrency); - }); - public static IUserViewManager UserViewManager { get; set; } /// <summary> @@ -491,7 +480,7 @@ namespace MediaBrowser.Controller.Entities private async Task RefreshAllMetadataForContainer(IMetadataContainer container, MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken) { // limit the amount of concurrent metadata refreshes - await RunMetadataRefresh( + await ProviderManager.RunMetadataRefresh( async () => { var series = container as Series; @@ -518,7 +507,7 @@ namespace MediaBrowser.Controller.Entities if (refreshOptions.RefreshItem(child)) { // limit the amount of concurrent metadata refreshes - await RunMetadataRefresh( + await ProviderManager.RunMetadataRefresh( async () => await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); } @@ -1252,26 +1241,6 @@ namespace MediaBrowser.Controller.Entities return true; } - /// <summary> - /// Runs multiple metadata refreshes concurrently. - /// </summary> - /// <param name="action">The action to run.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns> - private static async Task RunMetadataRefresh(Func<Task> action, CancellationToken cancellationToken) - { - await _metadataRefreshThrottler.Value.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - await action().ConfigureAwait(false); - } - finally - { - _metadataRefreshThrottler.Value.Release(); - } - } - public List<BaseItem> GetChildren(User user, bool includeLinkedChildren) { if (user == null) diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index 996ec27c0..0a4967223 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -46,6 +46,14 @@ namespace MediaBrowser.Controller.Providers Task<ItemUpdateType> RefreshSingleItem(BaseItem item, MetadataRefreshOptions options, CancellationToken cancellationToken); /// <summary> + /// Runs multiple metadata refreshes concurrently. + /// </summary> + /// <param name="action">The action to run.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns> + Task RunMetadataRefresh(Func<Task> action, CancellationToken cancellationToken); + + /// <summary> /// Saves the image. /// </summary> /// <param name="item">The item.</param> diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index e7e44876d..fbf4bc68b 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -1167,6 +1167,26 @@ namespace MediaBrowser.Providers.Manager return RefreshItem(item, options, cancellationToken); } + /// <summary> + /// Runs multiple metadata refreshes concurrently. + /// </summary> + /// <param name="action">The action to run.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns> + public async Task RunMetadataRefresh(Func<Task> action, CancellationToken cancellationToken) + { + await _baseItemManager.MetadataRefreshThrottler.Value.WaitAsync(cancellationToken).ConfigureAwait(false); + + try + { + await action().ConfigureAwait(false); + } + finally + { + _baseItemManager.MetadataRefreshThrottler.Value.Release(); + } + } + /// <inheritdoc/> public void Dispose() { |
