From a69ca6c55bb7183d247c2c3b25203dbed99fd5d9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 6 Oct 2016 14:55:01 -0400 Subject: avoid buffering http responses --- .../BaseApplicationHost.cs | 8 +++++- .../HttpClientManager/HttpClientManager.cs | 15 ++++++----- .../IO/MemoryStreamProvider.cs | 31 ++++++++++++++++++++++ .../Logging/NLogger.cs | 10 +++++++ .../MediaBrowser.Common.Implementations.csproj | 5 ++++ .../Security/PluginSecurityManager.cs | 6 +++-- .../Updates/GithubUpdater.cs | 6 +++-- .../packages.config | 1 + 8 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 MediaBrowser.Common.Implementations/IO/MemoryStreamProvider.cs (limited to 'MediaBrowser.Common.Implementations') diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index baf5afc1b..4099c9c56 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -30,6 +30,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Common.IO; namespace MediaBrowser.Common.Implementations { @@ -192,6 +193,8 @@ namespace MediaBrowser.Common.Implementations get { return Environment.OSVersion.VersionString; } } + public IMemoryStreamProvider MemoryStreamProvider { get; set; } + /// /// Initializes a new instance of the class. /// @@ -231,6 +234,8 @@ namespace MediaBrowser.Common.Implementations JsonSerializer = CreateJsonSerializer(); + MemoryStreamProvider = new MemoryStreamProvider(); + OnLoggerLoaded(true); LogManager.LoggerLoaded += (s, e) => OnLoggerLoaded(false); @@ -456,6 +461,7 @@ namespace MediaBrowser.Common.Implementations RegisterSingleInstance(JsonSerializer); RegisterSingleInstance(XmlSerializer); + RegisterSingleInstance(MemoryStreamProvider); RegisterSingleInstance(LogManager); RegisterSingleInstance(Logger); @@ -464,7 +470,7 @@ namespace MediaBrowser.Common.Implementations RegisterSingleInstance(FileSystemManager); - HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager); + HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamProvider); RegisterSingleInstance(HttpClient); NetworkManager = CreateNetworkManager(LogManager.GetLogger("NetworkManager")); diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs index ba5964be5..eec18e985 100644 --- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -42,6 +42,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager private readonly IApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; + private readonly IMemoryStreamProvider _memoryStreamProvider; /// /// Initializes a new instance of the class. @@ -52,7 +53,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager /// appPaths /// or /// logger - public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem) + public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem, IMemoryStreamProvider memoryStreamProvider) { if (appPaths == null) { @@ -65,6 +66,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager _logger = logger; _fileSystem = fileSystem; + _memoryStreamProvider = memoryStreamProvider; _appPaths = appPaths; // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c @@ -269,6 +271,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager Url = url, ResourcePool = resourcePool, CancellationToken = cancellationToken, + BufferContent = resourcePool != null }); } @@ -329,7 +332,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager { using (var stream = _fileSystem.GetFileStream(responseCachePath, FileMode.Open, FileAccess.Read, FileShare.Read, true)) { - var memoryStream = new MemoryStream(); + var memoryStream = _memoryStreamProvider.CreateNew(); await stream.CopyToAsync(memoryStream).ConfigureAwait(false); memoryStream.Position = 0; @@ -363,7 +366,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager using (var responseStream = response.Content) { - var memoryStream = new MemoryStream(); + var memoryStream = _memoryStreamProvider.CreateNew(); await responseStream.CopyToAsync(memoryStream).ConfigureAwait(false); memoryStream.Position = 0; @@ -455,7 +458,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager using (var stream = httpResponse.GetResponseStream()) { - var memoryStream = new MemoryStream(); + var memoryStream = _memoryStreamProvider.CreateNew(); await stream.CopyToAsync(memoryStream).ConfigureAwait(false); @@ -550,7 +553,8 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager { Url = url, ResourcePool = resourcePool, - CancellationToken = cancellationToken + CancellationToken = cancellationToken, + BufferContent = resourcePool != null }, postData); } @@ -560,7 +564,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager /// /// The options. /// Task{System.String}. - /// progress public async Task GetTempFile(HttpRequestOptions options) { var response = await GetTempFileResponse(options).ConfigureAwait(false); diff --git a/MediaBrowser.Common.Implementations/IO/MemoryStreamProvider.cs b/MediaBrowser.Common.Implementations/IO/MemoryStreamProvider.cs new file mode 100644 index 000000000..364055283 --- /dev/null +++ b/MediaBrowser.Common.Implementations/IO/MemoryStreamProvider.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MediaBrowser.Common.IO; +using Microsoft.IO; + +namespace MediaBrowser.Common.Implementations.IO +{ + public class MemoryStreamProvider : IMemoryStreamProvider + { + readonly RecyclableMemoryStreamManager _manager = new RecyclableMemoryStreamManager(); + + public MemoryStream CreateNew() + { + return _manager.GetStream(); + } + + public MemoryStream CreateNew(int capacity) + { + return _manager.GetStream("RecyclableMemoryStream", capacity); + } + + public MemoryStream CreateNew(byte[] buffer) + { + return _manager.GetStream("RecyclableMemoryStream", buffer, 0, buffer.Length); + } + } +} diff --git a/MediaBrowser.Common.Implementations/Logging/NLogger.cs b/MediaBrowser.Common.Implementations/Logging/NLogger.cs index 29b618890..97bc437a0 100644 --- a/MediaBrowser.Common.Implementations/Logging/NLogger.cs +++ b/MediaBrowser.Common.Implementations/Logging/NLogger.cs @@ -72,6 +72,11 @@ namespace MediaBrowser.Common.Implementations.Logging /// The param list. public void Debug(string message, params object[] paramList) { + if (_logManager.LogSeverity == LogSeverity.Info) + { + return; + } + _logger.Debug(message, paramList); } @@ -137,6 +142,11 @@ namespace MediaBrowser.Common.Implementations.Logging /// Content of the additional. public void LogMultiline(string message, LogSeverity severity, StringBuilder additionalContent) { + if (severity == LogSeverity.Debug && _logManager.LogSeverity == LogSeverity.Info) + { + return; + } + additionalContent.Insert(0, message + Environment.NewLine); const char tabChar = '\t'; diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index 7e8823bc0..718e6b9f6 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -51,6 +51,10 @@ False ..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll + + ..\packages\Microsoft.IO.RecyclableMemoryStream.1.1.0.0\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll + True + ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll @@ -93,6 +97,7 @@ + diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs index 10c0f8fc9..5d440609e 100644 --- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs +++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs @@ -169,7 +169,8 @@ namespace MediaBrowser.Common.Implementations.Security var options = new HttpRequestOptions() { Url = AppstoreRegUrl, - CancellationToken = CancellationToken.None + CancellationToken = CancellationToken.None, + BufferContent = false }; options.RequestHeaders.Add("X-Emby-Token", _appHost.SystemId); options.RequestContent = parameters; @@ -269,7 +270,8 @@ namespace MediaBrowser.Common.Implementations.Security Url = MBValidateUrl, // Seeing block length errors - EnableHttpCompression = false + EnableHttpCompression = false, + BufferContent = false }; options.SetPostData(data); diff --git a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs index 84c08439e..371c2ea11 100644 --- a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs +++ b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs @@ -30,7 +30,8 @@ namespace MediaBrowser.Common.Implementations.Updates Url = url, EnableKeepAlive = false, CancellationToken = cancellationToken, - UserAgent = "Emby/3.0" + UserAgent = "Emby/3.0", + BufferContent = false }; if (cacheLength.Ticks > 0) @@ -105,7 +106,8 @@ namespace MediaBrowser.Common.Implementations.Updates Url = url, EnableKeepAlive = false, CancellationToken = cancellationToken, - UserAgent = "Emby/3.0" + UserAgent = "Emby/3.0", + BufferContent = false }; using (var stream = await _httpClient.Get(options).ConfigureAwait(false)) diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index f444a3a05..40c727a06 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -1,6 +1,7 @@  + -- cgit v1.2.3