Reduce bottlenecks scan code (#9863)

This commit is contained in:
Bond-009 2023-06-22 05:01:47 +02:00 committed by GitHub
parent d14b1a1600
commit 3982b0e057
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 64 additions and 219 deletions

View File

@ -969,12 +969,8 @@ public class LibraryController : BaseJellyfinApiController
|| string.Equals(name, "MusicBrainz", StringComparison.OrdinalIgnoreCase); || string.Equals(name, "MusicBrainz", StringComparison.OrdinalIgnoreCase);
} }
var metadataOptions = _serverConfigurationManager.Configuration.MetadataOptions var metadataOptions = _serverConfigurationManager.GetMetadataOptionsForType(type);
.Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) return metadataOptions is null || !metadataOptions.DisabledMetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase);
.ToArray();
return metadataOptions.Length == 0
|| metadataOptions.Any(i => !i.DisabledMetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase));
} }
private bool IsImageFetcherEnabledByDefault(string name, string type, bool isNewLibrary) private bool IsImageFetcherEnabledByDefault(string name, string type, bool isNewLibrary)
@ -995,15 +991,7 @@ public class LibraryController : BaseJellyfinApiController
|| string.Equals(name, "Image Extractor", StringComparison.OrdinalIgnoreCase); || string.Equals(name, "Image Extractor", StringComparison.OrdinalIgnoreCase);
} }
var metadataOptions = _serverConfigurationManager.Configuration.MetadataOptions var metadataOptions = _serverConfigurationManager.GetMetadataOptionsForType(type);
.Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) return metadataOptions is null || !metadataOptions.DisabledImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase);
.ToArray();
if (metadataOptions.Length == 0)
{
return true;
}
return metadataOptions.Any(i => !i.DisabledImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase));
} }
} }

View File

@ -1,11 +1,10 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Threading;
using Jellyfin.Extensions; using Jellyfin.Extensions;
using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Configuration;
namespace MediaBrowser.Controller.BaseItemManager namespace MediaBrowser.Controller.BaseItemManager
@ -15,8 +14,6 @@ namespace MediaBrowser.Controller.BaseItemManager
{ {
private readonly IServerConfigurationManager _serverConfigurationManager; private readonly IServerConfigurationManager _serverConfigurationManager;
private int _metadataRefreshConcurrency;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="BaseItemManager"/> class. /// Initializes a new instance of the <see cref="BaseItemManager"/> class.
/// </summary> /// </summary>
@ -24,16 +21,8 @@ namespace MediaBrowser.Controller.BaseItemManager
public BaseItemManager(IServerConfigurationManager serverConfigurationManager) public BaseItemManager(IServerConfigurationManager serverConfigurationManager)
{ {
_serverConfigurationManager = serverConfigurationManager; _serverConfigurationManager = serverConfigurationManager;
_metadataRefreshConcurrency = GetMetadataRefreshConcurrency();
SetupMetadataThrottler();
_serverConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated;
} }
/// <inheritdoc />
public SemaphoreSlim MetadataRefreshThrottler { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public bool IsMetadataFetcherEnabled(BaseItem baseItem, TypeOptions? libraryTypeOptions, string name) public bool IsMetadataFetcherEnabled(BaseItem baseItem, TypeOptions? libraryTypeOptions, string name)
{ {
@ -51,12 +40,11 @@ namespace MediaBrowser.Controller.BaseItemManager
if (libraryTypeOptions is not null) 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)); var itemConfig = _serverConfigurationManager.GetMetadataOptionsForType(baseItem.GetType().Name);
return itemConfig is null || !itemConfig.DisabledMetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase);
return itemConfig is null || !itemConfig.DisabledMetadataFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase);
} }
/// <inheritdoc /> /// <inheritdoc />
@ -76,50 +64,11 @@ namespace MediaBrowser.Controller.BaseItemManager
if (libraryTypeOptions is not null) if (libraryTypeOptions is not null)
{ {
return libraryTypeOptions.ImageFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase); return libraryTypeOptions.ImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase);
} }
var itemConfig = _serverConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, baseItem.GetType().Name, StringComparison.OrdinalIgnoreCase)); var itemConfig = _serverConfigurationManager.GetMetadataOptionsForType(baseItem.GetType().Name);
return itemConfig is null || !itemConfig.DisabledImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase);
return itemConfig is null || !itemConfig.DisabledImageFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Called when the configuration is updated.
/// It will refresh the metadata throttler if the relevant config changed.
/// </summary>
private void OnConfigurationUpdated(object? sender, EventArgs e)
{
int newMetadataRefreshConcurrency = GetMetadataRefreshConcurrency();
if (_metadataRefreshConcurrency != newMetadataRefreshConcurrency)
{
_metadataRefreshConcurrency = newMetadataRefreshConcurrency;
SetupMetadataThrottler();
}
}
/// <summary>
/// Creates the metadata refresh throttler.
/// </summary>
[MemberNotNull(nameof(MetadataRefreshThrottler))]
private void SetupMetadataThrottler()
{
MetadataRefreshThrottler = new SemaphoreSlim(_metadataRefreshConcurrency);
}
/// <summary>
/// Returns the metadata refresh concurrency.
/// </summary>
private int GetMetadataRefreshConcurrency()
{
var concurrency = _serverConfigurationManager.Configuration.LibraryMetadataRefreshConcurrency;
if (concurrency <= 0)
{
concurrency = Environment.ProcessorCount;
}
return concurrency;
} }
} }
} }

View File

@ -9,11 +9,6 @@ namespace MediaBrowser.Controller.BaseItemManager
/// </summary> /// </summary>
public interface IBaseItemManager public interface IBaseItemManager
{ {
/// <summary>
/// Gets the semaphore used to limit the amount of concurrent metadata refreshes.
/// </summary>
SemaphoreSlim MetadataRefreshThrottler { get; }
/// <summary> /// <summary>
/// Is metadata fetcher enabled. /// Is metadata fetcher enabled.
/// </summary> /// </summary>

View File

@ -59,7 +59,7 @@ namespace MediaBrowser.Controller.Entities.Audio
{ {
if (IsAccessedByName) if (IsAccessedByName)
{ {
return new List<BaseItem>(); return Enumerable.Empty<BaseItem>();
} }
return base.Children; return base.Children;

View File

@ -1244,14 +1244,6 @@ namespace MediaBrowser.Controller.Entities
return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken); return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken);
} }
protected virtual void TriggerOnRefreshStart()
{
}
protected virtual void TriggerOnRefreshComplete()
{
}
/// <summary> /// <summary>
/// Overrides the base implementation to refresh metadata for local trailers. /// Overrides the base implementation to refresh metadata for local trailers.
/// </summary> /// </summary>
@ -1260,8 +1252,6 @@ namespace MediaBrowser.Controller.Entities
/// <returns>true if a provider reports we changed.</returns> /// <returns>true if a provider reports we changed.</returns>
public async Task<ItemUpdateType> RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken) public async Task<ItemUpdateType> RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken)
{ {
TriggerOnRefreshStart();
var requiresSave = false; var requiresSave = false;
if (SupportsOwnedItems) if (SupportsOwnedItems)
@ -1281,21 +1271,14 @@ namespace MediaBrowser.Controller.Entities
} }
} }
try var refreshOptions = requiresSave
{ ? new MetadataRefreshOptions(options)
var refreshOptions = requiresSave {
? new MetadataRefreshOptions(options) ForceSave = true
{ }
ForceSave = true : options;
}
: options;
return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false); return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
}
finally
{
TriggerOnRefreshComplete();
}
} }
protected bool IsVisibleStandaloneInternal(User user, bool checkFolders) protected bool IsVisibleStandaloneInternal(User user, bool checkFolders)
@ -1367,7 +1350,7 @@ namespace MediaBrowser.Controller.Entities
private async Task<bool> RefreshExtras(BaseItem item, MetadataRefreshOptions options, IReadOnlyList<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken) private async Task<bool> RefreshExtras(BaseItem item, MetadataRefreshOptions options, IReadOnlyList<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{ {
var extras = LibraryManager.FindExtras(item, fileSystemChildren, options.DirectoryService).ToArray(); 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); var extrasChanged = !item.ExtraIds.SequenceEqual(newExtraIds);
if (!extrasChanged && !options.ReplaceAllMetadata && options.MetadataRefreshMode != MetadataRefreshMode.FullRefresh) if (!extrasChanged && !options.ReplaceAllMetadata && options.MetadataRefreshMode != MetadataRefreshMode.FullRefresh)

View File

@ -301,14 +301,6 @@ namespace MediaBrowser.Controller.Entities
return dictionary; return dictionary;
} }
protected override void TriggerOnRefreshStart()
{
}
protected override void TriggerOnRefreshComplete()
{
}
/// <summary> /// <summary>
/// Validates the children internal. /// Validates the children internal.
/// </summary> /// </summary>
@ -510,26 +502,17 @@ namespace MediaBrowser.Controller.Entities
private async Task RefreshAllMetadataForContainer(IMetadataContainer container, MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken) private async Task RefreshAllMetadataForContainer(IMetadataContainer container, MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
{ {
// limit the amount of concurrent metadata refreshes if (container is Series series)
await ProviderManager.RunMetadataRefresh( {
async () => await series.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
{ }
var series = container as Series;
if (series is not null)
{
await series.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
}
await container.RefreshAllMetadata(refreshOptions, progress, cancellationToken).ConfigureAwait(false); await container.RefreshAllMetadata(refreshOptions, progress, cancellationToken).ConfigureAwait(false);
},
cancellationToken).ConfigureAwait(false);
} }
private async Task RefreshChildMetadata(BaseItem child, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken) private async Task RefreshChildMetadata(BaseItem child, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
{ {
var container = child as IMetadataContainer; if (child is IMetadataContainer container)
if (container is not null)
{ {
await RefreshAllMetadataForContainer(container, refreshOptions, progress, cancellationToken).ConfigureAwait(false); await RefreshAllMetadataForContainer(container, refreshOptions, progress, cancellationToken).ConfigureAwait(false);
} }
@ -537,10 +520,7 @@ namespace MediaBrowser.Controller.Entities
{ {
if (refreshOptions.RefreshItem(child)) if (refreshOptions.RefreshItem(child))
{ {
// limit the amount of concurrent metadata refreshes await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
await ProviderManager.RunMetadataRefresh(
async () => await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false),
cancellationToken).ConfigureAwait(false);
} }
if (recursive && child is Folder folder) if (recursive && child is Folder folder)
@ -586,7 +566,7 @@ namespace MediaBrowser.Controller.Entities
} }
var fanoutConcurrency = ConfigurationManager.Configuration.LibraryScanFanoutConcurrency; var fanoutConcurrency = ConfigurationManager.Configuration.LibraryScanFanoutConcurrency;
var parallelism = fanoutConcurrency == 0 ? Environment.ProcessorCount : fanoutConcurrency; var parallelism = fanoutConcurrency > 0 ? fanoutConcurrency : 2 * Environment.ProcessorCount;
var actionBlock = new ActionBlock<int>( var actionBlock = new ActionBlock<int>(
async i => async i =>
@ -618,7 +598,7 @@ namespace MediaBrowser.Controller.Entities
for (var i = 0; i < childrenCount; i++) for (var i = 0; i < childrenCount; i++)
{ {
actionBlock.Post(i); await actionBlock.SendAsync(i).ConfigureAwait(false);
} }
actionBlock.Complete(); actionBlock.Complete();

View File

@ -1,8 +1,8 @@
#nullable disable
#pragma warning disable CS1591 #pragma warning disable CS1591
using System;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Configuration;
namespace MediaBrowser.Controller.Library namespace MediaBrowser.Controller.Library
@ -10,8 +10,15 @@ namespace MediaBrowser.Controller.Library
public static class MetadataConfigurationExtensions public static class MetadataConfigurationExtensions
{ {
public static MetadataConfiguration GetMetadataConfiguration(this IConfigurationManager config) public static MetadataConfiguration GetMetadataConfiguration(this IConfigurationManager config)
{ => config.GetConfiguration<MetadataConfiguration>("metadata");
return config.GetConfiguration<MetadataConfiguration>("metadata");
} /// <summary>
/// Gets the <see cref="MetadataOptions" /> for the specified type.
/// </summary>
/// <param name="config">The <see cref="IServerConfigurationManager"/>.</param>
/// <param name="type">The type to get the <see cref="MetadataOptions" /> for.</param>
/// <returns>The <see cref="MetadataOptions" /> for the specified type or <c>null</c>.</returns>
public static MetadataOptions? GetMetadataOptionsForType(this IServerConfigurationManager config, string type)
=> Array.Find(config.Configuration.MetadataOptions, i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase));
} }
} }

View File

@ -54,14 +54,6 @@ namespace MediaBrowser.Controller.Providers
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task<ItemUpdateType> RefreshSingleItem(BaseItem item, MetadataRefreshOptions options, CancellationToken cancellationToken); 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> /// <summary>
/// Saves the image. /// Saves the image.
/// </summary> /// </summary>
@ -207,15 +199,6 @@ namespace MediaBrowser.Controller.Providers
where TItemType : BaseItem, new() where TItemType : BaseItem, new()
where TLookupType : ItemLookupInfo; where TLookupType : ItemLookupInfo;
/// <summary>
/// Gets the search image.
/// </summary>
/// <param name="providerName">Name of the provider.</param>
/// <param name="url">The URL.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{HttpResponseInfo}.</returns>
Task<HttpResponseMessage> GetSearchImage(string providerName, string url, CancellationToken cancellationToken);
HashSet<Guid> GetRefreshQueue(); HashSet<Guid> GetRefreshQueue();
void OnRefreshStart(BaseItem item); void OnRefreshStart(BaseItem item);

View File

@ -57,7 +57,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
private readonly IServerConfigurationManager _serverConfig; private readonly IServerConfigurationManager _serverConfig;
private readonly string _startupOptionFFmpegPath; private readonly string _startupOptionFFmpegPath;
private readonly SemaphoreSlim _thumbnailResourcePool = new SemaphoreSlim(2, 2); private readonly SemaphoreSlim _thumbnailResourcePool;
private readonly object _runningProcessesLock = new object(); private readonly object _runningProcessesLock = new object();
private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>(); private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>();
@ -113,6 +113,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
_jsonSerializerOptions = new JsonSerializerOptions(JsonDefaults.Options); _jsonSerializerOptions = new JsonSerializerOptions(JsonDefaults.Options);
_jsonSerializerOptions.Converters.Add(new JsonBoolStringConverter()); _jsonSerializerOptions.Converters.Add(new JsonBoolStringConverter());
var semaphoreCount = 2 * Environment.ProcessorCount;
_thumbnailResourcePool = new SemaphoreSlim(semaphoreCount, semaphoreCount);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@ -189,7 +189,7 @@ namespace MediaBrowser.Model.Configuration
public NameValuePair[] ContentTypes { get; set; } = Array.Empty<NameValuePair>(); public NameValuePair[] ContentTypes { get; set; } = Array.Empty<NameValuePair>();
public int RemoteClientBitrateLimit { get; set; } = 0; public int RemoteClientBitrateLimit { get; set; }
public bool EnableFolderView { get; set; } = false; public bool EnableFolderView { get; set; } = false;
@ -203,7 +203,7 @@ namespace MediaBrowser.Model.Configuration
public bool EnableExternalContentInSuggestions { get; set; } = true; public bool EnableExternalContentInSuggestions { get; set; } = true;
public int ImageExtractionTimeoutMs { get; set; } = 0; public int ImageExtractionTimeoutMs { get; set; }
public PathSubstitution[] PathSubstitutions { get; set; } = Array.Empty<PathSubstitution>(); public PathSubstitution[] PathSubstitutions { get; set; } = Array.Empty<PathSubstitution>();
@ -251,7 +251,7 @@ namespace MediaBrowser.Model.Configuration
/// Gets or sets the dummy chapter duration in seconds, use 0 (zero) or less to disable generation alltogether. /// Gets or sets the dummy chapter duration in seconds, use 0 (zero) or less to disable generation alltogether.
/// </summary> /// </summary>
/// <value>The dummy chapters duration.</value> /// <value>The dummy chapters duration.</value>
public int DummyChapterDuration { get; set; } = 0; public int DummyChapterDuration { get; set; }
/// <summary> /// <summary>
/// Gets or sets the chapter image resolution. /// Gets or sets the chapter image resolution.
@ -263,6 +263,6 @@ namespace MediaBrowser.Model.Configuration
/// Gets or sets the limit for parallel image encoding. /// Gets or sets the limit for parallel image encoding.
/// </summary> /// </summary>
/// <value>The limit for parallel image encoding.</value> /// <value>The limit for parallel image encoding.</value>
public int ParallelImageEncodingLimit { get; set; } = 0; public int ParallelImageEncodingLimit { get; set; }
} }
} }

View File

@ -131,12 +131,12 @@ namespace MediaBrowser.Providers.Manager
{ {
var type = item.GetType(); var type = item.GetType();
var service = _metadataServices.FirstOrDefault(current => current.CanRefreshPrimary(type)); var service = _metadataServices.FirstOrDefault(current => current.CanRefreshPrimary(type))
service ??= _metadataServices.FirstOrDefault(current => current.CanRefresh(item)); ?? _metadataServices.FirstOrDefault(current => current.CanRefresh(item));
if (service is null) if (service is null)
{ {
_logger.LogError("Unable to find a metadata service for item of type {TypeName}", item.GetType().Name); _logger.LogError("Unable to find a metadata service for item of type {TypeName}", type.Name);
return Task.FromResult(ItemUpdateType.None); return Task.FromResult(ItemUpdateType.None);
} }
@ -160,7 +160,7 @@ namespace MediaBrowser.Providers.Manager
// TODO: Isolate this hack into the tvh plugin // TODO: Isolate this hack into the tvh plugin
if (string.IsNullOrEmpty(contentType)) if (string.IsNullOrEmpty(contentType))
{ {
if (url.IndexOf("/imagecache/", StringComparison.OrdinalIgnoreCase) != -1) if (url.Contains("/imagecache/", StringComparison.OrdinalIgnoreCase))
{ {
contentType = "image/png"; contentType = "image/png";
} }
@ -232,6 +232,11 @@ namespace MediaBrowser.Providers.Manager
providers = providers.Where(i => string.Equals(i.Name, providerName, StringComparison.OrdinalIgnoreCase)); providers = providers.Where(i => string.Equals(i.Name, providerName, StringComparison.OrdinalIgnoreCase));
} }
if (query.ImageType is not null)
{
providers = providers.Where(i => i.GetSupportedImages(item).Contains(query.ImageType.Value));
}
var preferredLanguage = item.GetPreferredMetadataLanguage(); var preferredLanguage = item.GetPreferredMetadataLanguage();
var tasks = providers.Select(i => GetImages(item, i, preferredLanguage, query.IncludeAllLanguages, cancellationToken, query.ImageType)); var tasks = providers.Select(i => GetImages(item, i, preferredLanguage, query.IncludeAllLanguages, cancellationToken, query.ImageType));
@ -568,13 +573,7 @@ namespace MediaBrowser.Providers.Manager
/// <inheritdoc/> /// <inheritdoc/>
public MetadataOptions GetMetadataOptions(BaseItem item) public MetadataOptions GetMetadataOptions(BaseItem item)
{ => _configurationManager.GetMetadataOptionsForType(item.GetType().Name) ?? new MetadataOptions();
var type = item.GetType().Name;
return _configurationManager.Configuration.MetadataOptions
.FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) ??
new MetadataOptions();
}
/// <inheritdoc/> /// <inheritdoc/>
public Task SaveMetadataAsync(BaseItem item, ItemUpdateType updateType) public Task SaveMetadataAsync(BaseItem item, ItemUpdateType updateType)
@ -809,27 +808,12 @@ namespace MediaBrowser.Providers.Manager
{ {
var results = await provider.GetSearchResults(searchInfo, cancellationToken).ConfigureAwait(false); var results = await provider.GetSearchResults(searchInfo, cancellationToken).ConfigureAwait(false);
var list = results.ToList(); foreach (var item in results)
foreach (var item in list)
{ {
item.SearchProviderName = provider.Name; item.SearchProviderName = provider.Name;
} }
return list; return results;
}
/// <inheritdoc/>
public Task<HttpResponseMessage> GetSearchImage(string providerName, string url, CancellationToken cancellationToken)
{
var provider = _metadataProviders.OfType<IRemoteSearchProvider>().FirstOrDefault(i => string.Equals(i.Name, providerName, StringComparison.OrdinalIgnoreCase));
if (provider is null)
{
throw new ArgumentException("Search provider not found.");
}
return provider.GetImageResponse(url, cancellationToken);
} }
private IEnumerable<IExternalId> GetExternalIds(IHasProviderIds item) private IEnumerable<IExternalId> GetExternalIds(IHasProviderIds item)
@ -1102,29 +1086,6 @@ namespace MediaBrowser.Providers.Manager
return RefreshItem(item, options, cancellationToken); 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)
{
// create a variable for this since it is possible MetadataRefreshThrottler could change due to a config update during a scan
var metadataRefreshThrottler = _baseItemManager.MetadataRefreshThrottler;
await metadataRefreshThrottler.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
await action().ConfigureAwait(false);
}
finally
{
metadataRefreshThrottler.Release();
}
}
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() public void Dispose()
{ {

View File

@ -64,7 +64,7 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
{ {
var thumbsPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotestudiothumbs.txt"); var thumbsPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotestudiothumbs.txt");
thumbsPath = await EnsureThumbsList(thumbsPath, cancellationToken).ConfigureAwait(false); await EnsureThumbsList(thumbsPath, cancellationToken).ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
@ -107,7 +107,7 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
return string.Format(CultureInfo.InvariantCulture, "{0}/images/{1}/{2}.jpg", GetRepositoryUrl(), image, filename); return string.Format(CultureInfo.InvariantCulture, "{0}/images/{1}/{2}.jpg", GetRepositoryUrl(), image, filename);
} }
private Task<string> EnsureThumbsList(string file, CancellationToken cancellationToken) private Task EnsureThumbsList(string file, CancellationToken cancellationToken)
{ {
string url = string.Format(CultureInfo.InvariantCulture, "{0}/thumbs.txt", GetRepositoryUrl()); string url = string.Format(CultureInfo.InvariantCulture, "{0}/thumbs.txt", GetRepositoryUrl());
@ -129,7 +129,7 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
/// <param name="fileSystem">The file system.</param> /// <param name="fileSystem">The file system.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A Task to ensure existence of a file listing.</returns> /// <returns>A Task to ensure existence of a file listing.</returns>
public async Task<string> EnsureList(string url, string file, IFileSystem fileSystem, CancellationToken cancellationToken) public async Task EnsureList(string url, string file, IFileSystem fileSystem, CancellationToken cancellationToken)
{ {
var fileInfo = fileSystem.GetFileInfo(file); var fileInfo = fileSystem.GetFileInfo(file);
@ -148,8 +148,6 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
} }
} }
} }
return file;
} }
/// <summary> /// <summary>

View File

@ -50,14 +50,12 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
/// <param name="appPaths">The server application paths.</param> /// <param name="appPaths">The server application paths.</param>
/// <param name="fileSystem">The filesystem.</param> /// <param name="fileSystem">The filesystem.</param>
/// <param name="imageEncoder">The image encoder.</param> /// <param name="imageEncoder">The image encoder.</param>
/// <param name="mediaEncoder">The media encoder.</param>
/// <param name="config">The configuration.</param> /// <param name="config">The configuration.</param>
public ImageProcessor( public ImageProcessor(
ILogger<ImageProcessor> logger, ILogger<ImageProcessor> logger,
IServerApplicationPaths appPaths, IServerApplicationPaths appPaths,
IFileSystem fileSystem, IFileSystem fileSystem,
IImageEncoder imageEncoder, IImageEncoder imageEncoder,
IMediaEncoder mediaEncoder,
IServerConfigurationManager config) IServerConfigurationManager config)
{ {
_logger = logger; _logger = logger;