From 937d27ae9d6aa571ab9327f138bfba1b84c158db Mon Sep 17 00:00:00 2001 From: LukePulverenti Luke Pulverenti luke pulverenti Date: Sun, 19 Aug 2012 16:38:31 -0400 Subject: One async call leads to another, and another, all the way up the call stack... --- .../Net/Handlers/BaseEmbeddedResourceHandler.cs | 6 +-- MediaBrowser.Common/Net/Handlers/BaseHandler.cs | 61 ++++++++-------------- .../Net/Handlers/BaseJsonHandler.cs | 37 +++++-------- .../Net/Handlers/StaticFileHandler.cs | 56 +++++++++----------- 4 files changed, 66 insertions(+), 94 deletions(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/Handlers/BaseEmbeddedResourceHandler.cs b/MediaBrowser.Common/Net/Handlers/BaseEmbeddedResourceHandler.cs index 2fcead05b0..a8c7090f7d 100644 --- a/MediaBrowser.Common/Net/Handlers/BaseEmbeddedResourceHandler.cs +++ b/MediaBrowser.Common/Net/Handlers/BaseEmbeddedResourceHandler.cs @@ -14,9 +14,9 @@ namespace MediaBrowser.Common.Net.Handlers protected string ResourcePath { get; set; } - public override string ContentType + public override Task GetContentType() { - get + return Task.Run(() => { string extension = Path.GetExtension(ResourcePath); @@ -46,7 +46,7 @@ namespace MediaBrowser.Common.Net.Handlers } return "text/plain; charset=utf-8"; - } + }); } protected override Task WriteResponseToOutputStream(Stream stream) diff --git a/MediaBrowser.Common/Net/Handlers/BaseHandler.cs b/MediaBrowser.Common/Net/Handlers/BaseHandler.cs index f9ef065ecc..7a4efdaf2b 100644 --- a/MediaBrowser.Common/Net/Handlers/BaseHandler.cs +++ b/MediaBrowser.Common/Net/Handlers/BaseHandler.cs @@ -111,7 +111,7 @@ namespace MediaBrowser.Common.Net.Handlers /// /// Gets the MIME type to include in the response headers /// - public abstract string ContentType { get; } + public abstract Task GetContentType(); /// /// Gets the status code to include in the response headers @@ -129,31 +129,9 @@ namespace MediaBrowser.Common.Net.Handlers } } - private bool _LastDateModifiedDiscovered = false; - private DateTime? _LastDateModified = null; - /// - /// Gets the last date modified of the content being returned, if this can be determined. - /// This will be used to invalidate the cache, so it's not needed if CacheDuration is 0. - /// - public DateTime? LastDateModified + public virtual bool ShouldCompressResponse(string contentType) { - get - { - if (!_LastDateModifiedDiscovered) - { - _LastDateModified = GetLastDateModified(); - } - - return _LastDateModified; - } - } - - public virtual bool CompressResponse - { - get - { - return true; - } + return true; } private bool ClientSupportsCompression @@ -207,10 +185,12 @@ namespace MediaBrowser.Common.Net.Handlers // When serving a range request, we need to return status code 206 to indicate a partial response body StatusCode = SupportsByteRangeRequests && IsRangeRequest ? 206 : 200; - ctx.Response.ContentType = ContentType; + ctx.Response.ContentType = await GetContentType(); TimeSpan cacheDuration = CacheDuration; + DateTime? lastDateModified = await GetLastDateModified(); + if (ctx.Request.Headers.AllKeys.Contains("If-Modified-Since")) { DateTime ifModifiedSince; @@ -218,18 +198,20 @@ namespace MediaBrowser.Common.Net.Handlers if (DateTime.TryParse(ctx.Request.Headers["If-Modified-Since"].Replace(" GMT", string.Empty), out ifModifiedSince)) { // If the cache hasn't expired yet just return a 304 - if (IsCacheValid(ifModifiedSince, cacheDuration, LastDateModified)) + if (IsCacheValid(ifModifiedSince, cacheDuration, lastDateModified)) { StatusCode = 304; } } } - PrepareResponse(); + await PrepareResponse(); if (IsResponseValid) { - await ProcessUncachedRequest(ctx, cacheDuration); + bool compressResponse = ShouldCompressResponse(ctx.Response.ContentType) && ClientSupportsCompression; + + await ProcessUncachedRequest(ctx, compressResponse, cacheDuration, lastDateModified); } else { @@ -241,7 +223,7 @@ namespace MediaBrowser.Common.Net.Handlers { // It might be too late if some response data has already been transmitted, but try to set this ctx.Response.StatusCode = 500; - + Logger.LogException(ex); } finally @@ -250,7 +232,7 @@ namespace MediaBrowser.Common.Net.Handlers } } - private async Task ProcessUncachedRequest(HttpListenerContext ctx, TimeSpan cacheDuration) + private async Task ProcessUncachedRequest(HttpListenerContext ctx, bool compressResponse, TimeSpan cacheDuration, DateTime? lastDateModified) { long? totalContentLength = TotalContentLength; @@ -270,7 +252,7 @@ namespace MediaBrowser.Common.Net.Handlers } // Add the compression header - if (CompressResponse && ClientSupportsCompression) + if (compressResponse) { ctx.Response.AddHeader("Content-Encoding", CompressionMethod); } @@ -278,7 +260,7 @@ namespace MediaBrowser.Common.Net.Handlers // Add caching headers if (cacheDuration.Ticks > 0) { - CacheResponse(ctx.Response, cacheDuration, LastDateModified); + CacheResponse(ctx.Response, cacheDuration, lastDateModified); } // Set the status code @@ -289,7 +271,7 @@ namespace MediaBrowser.Common.Net.Handlers // Finally, write the response data Stream outputStream = ctx.Response.OutputStream; - if (CompressResponse && ClientSupportsCompression) + if (compressResponse) { if (CompressionMethod.Equals("deflate", StringComparison.OrdinalIgnoreCase)) { @@ -321,10 +303,11 @@ namespace MediaBrowser.Common.Net.Handlers } /// - /// Gives subclasses a chance to do and prep work, and also to validate data and set an error status code, if needed + /// Gives subclasses a chance to do any prep work, and also to validate data and set an error status code, if needed /// - protected virtual void PrepareResponse() + protected virtual Task PrepareResponse() { + return Task.Run(() => { }); } protected abstract Task WriteResponseToOutputStream(Stream stream); @@ -372,9 +355,11 @@ namespace MediaBrowser.Common.Net.Handlers return null; } - protected virtual DateTime? GetLastDateModified() + protected virtual Task GetLastDateModified() { - return null; + DateTime? value = null; + + return Task.Run(() => { return value; }); } private bool IsResponseValid diff --git a/MediaBrowser.Common/Net/Handlers/BaseJsonHandler.cs b/MediaBrowser.Common/Net/Handlers/BaseJsonHandler.cs index a35af92313..a3a47a4a33 100644 --- a/MediaBrowser.Common/Net/Handlers/BaseJsonHandler.cs +++ b/MediaBrowser.Common/Net/Handlers/BaseJsonHandler.cs @@ -6,19 +6,22 @@ namespace MediaBrowser.Common.Net.Handlers { public abstract class BaseJsonHandler : BaseHandler { - public override string ContentType + public override Task GetContentType() { - get { return MimeTypes.JsonMimeType; } + return Task.Run(() => + { + return MimeTypes.JsonMimeType; + }); } private bool _ObjectToSerializeEnsured = false; private T _ObjectToSerialize; - private void EnsureObjectToSerialize() + private async Task EnsureObjectToSerialize() { if (!_ObjectToSerializeEnsured) { - _ObjectToSerialize = GetObjectToSerialize(); + _ObjectToSerialize = await GetObjectToSerialize(); if (_ObjectToSerialize == null) { @@ -29,30 +32,18 @@ namespace MediaBrowser.Common.Net.Handlers } } - private T ObjectToSerialize - { - get - { - EnsureObjectToSerialize(); - return _ObjectToSerialize; - } - } + protected abstract Task GetObjectToSerialize(); - protected abstract T GetObjectToSerialize(); - - protected override void PrepareResponse() + protected override async Task PrepareResponse() { - base.PrepareResponse(); - - EnsureObjectToSerialize(); + await EnsureObjectToSerialize(); } - protected override Task WriteResponseToOutputStream(Stream stream) + protected async override Task WriteResponseToOutputStream(Stream stream) { - return Task.Run(() => - { - JsonSerializer.SerializeToStream(ObjectToSerialize, stream); - }); + await EnsureObjectToSerialize(); + + JsonSerializer.SerializeToStream(_ObjectToSerialize, stream); } } } diff --git a/MediaBrowser.Common/Net/Handlers/StaticFileHandler.cs b/MediaBrowser.Common/Net/Handlers/StaticFileHandler.cs index 5656f92739..d8971dd97d 100644 --- a/MediaBrowser.Common/Net/Handlers/StaticFileHandler.cs +++ b/MediaBrowser.Common/Net/Handlers/StaticFileHandler.cs @@ -77,27 +77,22 @@ namespace MediaBrowser.Common.Net.Handlers } } - public override bool CompressResponse + public override bool ShouldCompressResponse(string contentType) { - get + // Can't compress these + if (IsRangeRequest) { - // Can't compress these - if (IsRangeRequest) - { - return false; - } - - string contentType = ContentType; - - // Don't compress media - if (contentType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase) || contentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) - { - return false; - } + return false; + } - // It will take some work to support compression within this handler + // Don't compress media + if (contentType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase) || contentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) + { return false; } + + // It will take some work to support compression within this handler + return false; } protected override long? GetTotalContentLength() @@ -105,31 +100,32 @@ namespace MediaBrowser.Common.Net.Handlers return SourceStream.Length; } - protected override DateTime? GetLastDateModified() + protected override Task GetLastDateModified() { - EnsureSourceStream(); - - if (SourceStream == null) + return Task.Run(() => { - return null; - } + EnsureSourceStream(); + + if (SourceStream == null) + { + return null; + } - return File.GetLastWriteTime(Path); + return File.GetLastWriteTime(Path); + }); } - public override string ContentType + public override Task GetContentType() { - get + return Task.Run(() => { return MimeTypes.GetMimeType(Path); - } + }); } - protected override void PrepareResponse() + protected override Task PrepareResponse() { - base.PrepareResponse(); - - EnsureSourceStream(); + return Task.Run(() => { EnsureSourceStream(); }); } protected async override Task WriteResponseToOutputStream(Stream stream) -- cgit v1.2.3