diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs
index 1f7361d2f6..305bede564 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,12 +203,51 @@ namespace MediaBrowser.Server.Implementations.Drawing
}
}
}
- finally
+ catch
{
semaphore.Release();
+
+ throw;
}
}
+ ///
+ /// Caches the resized image.
+ ///
+ /// The cache file path.
+ /// The bytes.
+ /// The semaphore.
+ 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();
+ }
+ });
+ }
+
///
/// Sets the color of the background.
///
@@ -363,28 +403,6 @@ namespace MediaBrowser.Server.Implementations.Drawing
return croppedImagePath;
}
- ///
- /// Caches the resized image.
- ///
- /// The cache file path.
- /// The bytes.
- 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);
- }
- }
-
///
/// Gets the cache file path based on a set of parameters
///
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs
index f6547dec17..4f795fdd5f 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs
@@ -314,6 +314,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer
/// The CTX.
private async void ProcessHttpRequestAsync(HttpListenerContext context)
{
+ var date = DateTime.Now;
+
LogHttpRequest(context);
if (context.Request.IsWebSocketRequest)
@@ -360,7 +362,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer
var url = context.Request.Url.ToString();
var endPoint = context.Request.RemoteEndPoint;
- LogResponse(context, url, endPoint);
+ var duration = DateTime.Now - date;
+
+ LogResponse(context, url, endPoint, duration);
}
catch (Exception ex)
@@ -461,14 +465,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer
/// The CTX.
/// The URL.
/// The end point.
- private void LogResponse(HttpListenerContext ctx, string url, IPEndPoint endPoint)
+ /// The duration.
+ private void LogResponse(HttpListenerContext ctx, string url, IPEndPoint endPoint, TimeSpan duration)
{
if (!EnableHttpRequestLogging)
{
return;
}
- var statusode = ctx.Response.StatusCode;
+ var statusCode = ctx.Response.StatusCode;
var log = new StringBuilder();
@@ -476,7 +481,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer
log.AppendLine("Headers: " + string.Join(",", ctx.Response.Headers.AllKeys.Select(k => k + "=" + ctx.Response.Headers[k])));
- var msg = "Http Response Sent (" + statusode + ") to " + endPoint;
+ var responseTime = string.Format(". Response time: {0} ms", duration.TotalMilliseconds);
+
+ var msg = "Response code " + statusCode + " sent to " + endPoint + responseTime;
_logger.LogMultiline(msg, LogSeverity.Debug, log);
}