aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2013-09-23 20:04:02 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2013-09-23 20:04:02 -0400
commitcbd767ddcef7a857fb48d1cdb13e79e0ebf201b7 (patch)
treeff7084f61b85d0cf97327501c22b7be67058422a /MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs
parentbb281d4bcc56f0ea923e14d352d057a74587c33d (diff)
improve image serving performance slightly
Diffstat (limited to 'MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs')
-rw-r--r--MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs94
1 files changed, 56 insertions, 38 deletions
diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs
index 1f7361d2f..305bede56 100644
--- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs
+++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs
@@ -121,7 +121,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
}
catch (IOException)
{
- // Cache file doesn't exist or is currently being written ro
+ // Cache file doesn't exist or is currently being written to
}
var semaphore = GetLock(cacheFilePath);
@@ -129,21 +129,24 @@ namespace MediaBrowser.Server.Implementations.Drawing
await semaphore.WaitAsync().ConfigureAwait(false);
// Check again in case of lock contention
- if (File.Exists(cacheFilePath))
+ try
{
- try
- {
- using (var fileStream = new FileStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
- {
- await fileStream.CopyToAsync(toStream).ConfigureAwait(false);
- return;
- }
- }
- finally
+ using (var fileStream = new FileStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
{
+ await fileStream.CopyToAsync(toStream).ConfigureAwait(false);
semaphore.Release();
+ return;
}
}
+ catch (IOException)
+ {
+ // Cache file doesn't exist or is currently being written to
+ }
+ catch
+ {
+ semaphore.Release();
+ throw;
+ }
try
{
@@ -188,12 +191,10 @@ namespace MediaBrowser.Server.Implementations.Drawing
var bytes = outputMemoryStream.ToArray();
- var outputTask = toStream.WriteAsync(bytes, 0, bytes.Length);
+ await toStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
// kick off a task to cache the result
- var cacheTask = CacheResizedImage(cacheFilePath, bytes);
-
- await Task.WhenAll(outputTask, cacheTask).ConfigureAwait(false);
+ CacheResizedImage(cacheFilePath, bytes, semaphore);
}
}
}
@@ -202,13 +203,52 @@ namespace MediaBrowser.Server.Implementations.Drawing
}
}
}
- finally
+ catch
{
semaphore.Release();
+
+ throw;
}
}
/// <summary>
+ /// Caches the resized image.
+ /// </summary>
+ /// <param name="cacheFilePath">The cache file path.</param>
+ /// <param name="bytes">The bytes.</param>
+ /// <param name="semaphore">The semaphore.</param>
+ private void CacheResizedImage(string cacheFilePath, byte[] bytes, SemaphoreSlim semaphore)
+ {
+ Task.Run(async () =>
+ {
+ try
+ {
+ var parentPath = Path.GetDirectoryName(cacheFilePath);
+
+ if (!Directory.Exists(parentPath))
+ {
+ Directory.CreateDirectory(parentPath);
+ }
+
+ // Save to the cache location
+ using (var cacheFileStream = new FileStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
+ {
+ // Save to the filestream
+ await cacheFileStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error writing to image cache file {0}", ex, cacheFilePath);
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ });
+ }
+
+ /// <summary>
/// Sets the color of the background.
/// </summary>
/// <param name="graphics">The graphics.</param>
@@ -364,28 +404,6 @@ namespace MediaBrowser.Server.Implementations.Drawing
}
/// <summary>
- /// Caches the resized image.
- /// </summary>
- /// <param name="cacheFilePath">The cache file path.</param>
- /// <param name="bytes">The bytes.</param>
- private async Task CacheResizedImage(string cacheFilePath, byte[] bytes)
- {
- var parentPath = Path.GetDirectoryName(cacheFilePath);
-
- if (!Directory.Exists(parentPath))
- {
- Directory.CreateDirectory(parentPath);
- }
-
- // Save to the cache location
- using (var cacheFileStream = new FileStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
- {
- // Save to the filestream
- await cacheFileStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
- }
- }
-
- /// <summary>
/// Gets the cache file path based on a set of parameters
/// </summary>
private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageOutputFormat format, ImageOverlay? overlay, int percentPlayed, string backgroundColor)