aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2015-04-23 12:50:54 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2015-04-23 12:50:54 -0400
commit6f016525208f665502d844d151c31e9ff38fd20a (patch)
treed9c5905af8a4684b13eb6eb00584bfbb66a4e1fc
parent7ac8fd1c68ec9b58d17180b50a2555dd469ba535 (diff)
control the number of simultaneous image operations
-rw-r--r--Emby.Drawing/ImageProcessor.cs49
-rw-r--r--MediaBrowser.Controller/Drawing/IImageProcessor.cs2
-rw-r--r--MediaBrowser.Model/Configuration/EncodingOptions.cs2
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs24
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserManager.cs16
-rw-r--r--MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs34
-rw-r--r--MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs6
7 files changed, 85 insertions, 48 deletions
diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs
index 55c6f6455..6365bd294 100644
--- a/Emby.Drawing/ImageProcessor.cs
+++ b/Emby.Drawing/ImageProcessor.cs
@@ -51,6 +51,7 @@ namespace Emby.Drawing
private readonly IJsonSerializer _jsonSerializer;
private readonly IServerApplicationPaths _appPaths;
private readonly IImageEncoder _imageEncoder;
+ private readonly SemaphoreSlim _imageProcessingSemaphore;
public ImageProcessor(ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem, IJsonSerializer jsonSerializer, IImageEncoder imageEncoder)
{
@@ -88,6 +89,8 @@ namespace Emby.Drawing
}
_cachedImagedSizes = new ConcurrentDictionary<Guid, ImageSize>(sizeDictionary);
+ var count = Environment.ProcessorCount;
+ _imageProcessingSemaphore = new SemaphoreSlim(count, count);
}
public string[] SupportedInputFormats
@@ -201,6 +204,8 @@ namespace Emby.Drawing
await semaphore.WaitAsync().ConfigureAwait(false);
+ var imageProcessingLockTaken = false;
+
try
{
CheckDisposed();
@@ -212,11 +217,20 @@ namespace Emby.Drawing
Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath));
+ await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false);
+
+ imageProcessingLockTaken = true;
+
_imageEncoder.EncodeImage(originalImagePath, cacheFilePath, newWidth, newHeight, quality, options);
}
}
finally
{
+ if (imageProcessingLockTaken)
+ {
+ _imageProcessingSemaphore.Release();
+ }
+
semaphore.Release();
}
@@ -254,10 +268,15 @@ namespace Emby.Drawing
return GetResult(croppedImagePath);
}
+ var imageProcessingLockTaken = false;
+
try
{
Directory.CreateDirectory(Path.GetDirectoryName(croppedImagePath));
+ await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false);
+ imageProcessingLockTaken = true;
+
_imageEncoder.CropWhiteSpace(originalImagePath, croppedImagePath);
}
catch (Exception ex)
@@ -269,6 +288,11 @@ namespace Emby.Drawing
}
finally
{
+ if (imageProcessingLockTaken)
+ {
+ _imageProcessingSemaphore.Release();
+ }
+
semaphore.Release();
}
@@ -592,13 +616,25 @@ namespace Emby.Drawing
return enhancedImagePath;
}
+ var imageProcessingLockTaken = false;
+
try
{
Directory.CreateDirectory(Path.GetDirectoryName(enhancedImagePath));
+
+ await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false);
+
+ imageProcessingLockTaken = true;
+
await ExecuteImageEnhancers(supportedEnhancers, originalImagePath, enhancedImagePath, item, imageType, imageIndex).ConfigureAwait(false);
}
finally
{
+ if (imageProcessingLockTaken)
+ {
+ _imageProcessingSemaphore.Release();
+ }
+
semaphore.Release();
}
@@ -717,9 +753,18 @@ namespace Emby.Drawing
return Path.Combine(path, filename);
}
- public void CreateImageCollage(ImageCollageOptions options)
+ public async Task CreateImageCollage(ImageCollageOptions options)
{
- _imageEncoder.CreateImageCollage(options);
+ await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false);
+
+ try
+ {
+ _imageEncoder.CreateImageCollage(options);
+ }
+ finally
+ {
+ _imageProcessingSemaphore.Release();
+ }
}
public IEnumerable<IImageEnhancer> GetSupportedEnhancers(IHasImages item, ImageType imageType)
diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
index 685d2706d..aeb817392 100644
--- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs
+++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
@@ -104,6 +104,6 @@ namespace MediaBrowser.Controller.Drawing
/// Creates the image collage.
/// </summary>
/// <param name="options">The options.</param>
- void CreateImageCollage(ImageCollageOptions options);
+ Task CreateImageCollage(ImageCollageOptions options);
}
}
diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs
index c44a7c94d..afd67eb15 100644
--- a/MediaBrowser.Model/Configuration/EncodingOptions.cs
+++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs
@@ -17,7 +17,7 @@ namespace MediaBrowser.Model.Configuration
DownMixAudioBoost = 2;
EncodingQuality = EncodingQuality.Auto;
EnableThrottling = true;
- ThrottleThresholdSeconds = 90;
+ ThrottleThresholdSeconds = 120;
}
}
}
diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
index 3fa0df760..2106a58de 100644
--- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
+++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
@@ -88,7 +88,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
NatUtility.UnhandledException += NatUtility_UnhandledException;
NatUtility.StartDiscovery();
- _timer = new Timer(s => _createdRules = new List<string>(), null, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(3));
+ _timer = new Timer(s => _createdRules = new List<string>(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
_lastConfigIdentifier = GetConfigIdentifier();
@@ -97,17 +97,17 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
void NatUtility_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
- //var ex = e.ExceptionObject as Exception;
-
- //if (ex == null)
- //{
- // _logger.Error("Unidentified error reported by Mono.Nat");
- //}
- //else
- //{
- // // Seeing some blank exceptions coming through here
- // _logger.ErrorException("Error reported by Mono.Nat: ", ex);
- //}
+ var ex = e.ExceptionObject as Exception;
+
+ if (ex == null)
+ {
+ //_logger.Error("Unidentified error reported by Mono.Nat");
+ }
+ else
+ {
+ // Seeing some blank exceptions coming through here
+ _logger.ErrorException("Error reported by Mono.Nat: ", ex);
+ }
}
void NatUtility_DeviceFound(object sender, DeviceEventArgs e)
diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs
index 03471a8e9..02e1795f3 100644
--- a/MediaBrowser.Server.Implementations/Library/UserManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs
@@ -345,7 +345,7 @@ namespace MediaBrowser.Server.Implementations.Library
{
var name = MakeValidUsername(Environment.UserName);
- var user = InstantiateNewUser(name, false);
+ var user = InstantiateNewUser(name);
user.DateLastSaved = DateTime.UtcNow;
@@ -552,7 +552,7 @@ namespace MediaBrowser.Server.Implementations.Library
try
{
- var user = InstantiateNewUser(name, true);
+ var user = InstantiateNewUser(name);
var list = Users.ToList();
list.Add(user);
@@ -697,21 +697,13 @@ namespace MediaBrowser.Server.Implementations.Library
/// Instantiates the new user.
/// </summary>
/// <param name="name">The name.</param>
- /// <param name="checkId">if set to <c>true</c> [check identifier].</param>
/// <returns>User.</returns>
- private User InstantiateNewUser(string name, bool checkId)
+ private User InstantiateNewUser(string name)
{
- var id = ("MBUser" + name).GetMD5();
-
- if (checkId && Users.Select(i => i.Id).Contains(id))
- {
- id = Guid.NewGuid();
- }
-
return new User
{
Name = name,
- Id = id,
+ Id = Guid.NewGuid(),
DateCreated = DateTime.UtcNow,
DateModified = DateTime.UtcNow,
UsesIdForConfigurationPath = true
diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
index 15c43213f..be71a6408 100644
--- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
@@ -80,7 +80,7 @@ namespace MediaBrowser.Server.Implementations.Photos
{
var outputPath = Path.Combine(ApplicationPaths.TempDirectory, Guid.NewGuid() + ".png");
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
- var imageCreated = CreateImage(item, itemsWithImages, outputPath, imageType, 0);
+ var imageCreated = await CreateImage(item, itemsWithImages, outputPath, imageType, 0).ConfigureAwait(false);
if (!imageCreated)
{
@@ -103,9 +103,9 @@ namespace MediaBrowser.Server.Implementations.Photos
return parts.GetMD5().ToString("N");
}
- protected void CreateThumbCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, bool drawText)
+ protected Task CreateThumbCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, bool drawText)
{
- CreateCollage(primaryItem, items, outputPath, 960, 540, drawText, primaryItem.Name);
+ return CreateCollage(primaryItem, items, outputPath, 960, 540, drawText, primaryItem.Name);
}
protected virtual IEnumerable<string> GetStripCollageImagePaths(IHasImages primaryItem, IEnumerable<BaseItem> items)
@@ -115,22 +115,22 @@ namespace MediaBrowser.Server.Implementations.Photos
.Where(i => !string.IsNullOrWhiteSpace(i));
}
- protected void CreatePosterCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath)
+ protected Task CreatePosterCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath)
{
- CreateCollage(primaryItem, items, outputPath, 600, 900, true, primaryItem.Name);
+ return CreateCollage(primaryItem, items, outputPath, 600, 900, true, primaryItem.Name);
}
- protected void CreateSquareCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, bool drawText)
+ protected Task CreateSquareCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, bool drawText)
{
- CreateCollage(primaryItem, items, outputPath, 800, 800, drawText, primaryItem.Name);
+ return CreateCollage(primaryItem, items, outputPath, 800, 800, drawText, primaryItem.Name);
}
- protected void CreateThumbCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, int width, int height, bool drawText, string text)
+ protected Task CreateThumbCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, int width, int height, bool drawText, string text)
{
- CreateCollage(primaryItem, items, outputPath, width, height, drawText, text);
+ return CreateCollage(primaryItem, items, outputPath, width, height, drawText, text);
}
- private void CreateCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, int width, int height, bool drawText, string text)
+ private Task CreateCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, int width, int height, bool drawText, string text)
{
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
@@ -143,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.Photos
InputPaths = GetStripCollageImagePaths(primaryItem, items).ToArray()
};
- ImageProcessor.CreateImageCollage(options);
+ return ImageProcessor.CreateImageCollage(options);
}
public string Name
@@ -151,7 +151,7 @@ namespace MediaBrowser.Server.Implementations.Photos
get { return "Dynamic Image Provider"; }
}
- protected virtual bool CreateImage(IHasImages item,
+ protected virtual async Task<bool> CreateImage(IHasImages item,
List<BaseItem> itemsWithImages,
string outputPath,
ImageType imageType,
@@ -166,7 +166,7 @@ namespace MediaBrowser.Server.Implementations.Photos
if (imageType == ImageType.Thumb)
{
- CreateThumbCollage(item, itemsWithImages, outputPath, drawText);
+ await CreateThumbCollage(item, itemsWithImages, outputPath, drawText).ConfigureAwait(false);
return true;
}
@@ -174,15 +174,15 @@ namespace MediaBrowser.Server.Implementations.Photos
{
if (item is UserView)
{
- CreateSquareCollage(item, itemsWithImages, outputPath, drawText);
+ await CreateSquareCollage(item, itemsWithImages, outputPath, drawText).ConfigureAwait(false);
}
else if (item is PhotoAlbum || item is Playlist)
{
- CreateSquareCollage(item, itemsWithImages, outputPath, drawText);
+ await CreateSquareCollage(item, itemsWithImages, outputPath, drawText).ConfigureAwait(false);
}
else
{
- CreatePosterCollage(item, itemsWithImages, outputPath);
+ await CreatePosterCollage(item, itemsWithImages, outputPath).ConfigureAwait(false);
}
return true;
@@ -234,7 +234,7 @@ namespace MediaBrowser.Server.Implementations.Photos
protected virtual List<BaseItem> GetFinalItems(List<BaseItem> items, int limit)
{
// Rotate the images once every x days
- var random = DateTime.Now.DayOfYear % 5;
+ var random = DateTime.Now.DayOfYear % 7;
return items
.OrderBy(i => (random + "" + items.IndexOf(i)).GetMD5())
diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs
index 4a4d90d14..24dc2cc1d 100644
--- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs
@@ -216,7 +216,7 @@ namespace MediaBrowser.Server.Implementations.UserViews
return collectionStripViewTypes.Contains(view.ViewType ?? string.Empty);
}
- protected override bool CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPath, ImageType imageType, int imageIndex)
+ protected override async Task<bool> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPath, ImageType imageType, int imageIndex)
{
var view = (UserView)item;
if (imageType == ImageType.Primary && IsUsingCollectionStrip(view))
@@ -226,11 +226,11 @@ namespace MediaBrowser.Server.Implementations.UserViews
return false;
}
- CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540, false, item.Name);
+ await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540, false, item.Name).ConfigureAwait(false);
return true;
}
- return base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex);
+ return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false);
}
protected override IEnumerable<String> GetStripCollageImagePaths(IHasImages primaryItem, IEnumerable<BaseItem> items)