diff --git a/benchmarks/Kestrel.Performance/Http1ConnectionParsingOverheadBenchmark.cs b/benchmarks/Kestrel.Performance/Http1ConnectionParsingOverheadBenchmark.cs index b4979f4a3b..ff3fa369bf 100644 --- a/benchmarks/Kestrel.Performance/Http1ConnectionParsingOverheadBenchmark.cs +++ b/benchmarks/Kestrel.Performance/Http1ConnectionParsingOverheadBenchmark.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance public void Setup() { var memoryPool = new MemoryPool(); - var pair = PipeFactory.CreateConnectionPair(memoryPool); + var pair = DuplexPipe.CreateConnectionPair(memoryPool); var serviceContext = new ServiceContext { diff --git a/benchmarks/Kestrel.Performance/Http1WritingBenchmark.cs b/benchmarks/Kestrel.Performance/Http1WritingBenchmark.cs index 325b27c0e7..1f00d1e6cf 100644 --- a/benchmarks/Kestrel.Performance/Http1WritingBenchmark.cs +++ b/benchmarks/Kestrel.Performance/Http1WritingBenchmark.cs @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance private static readonly Func _psuedoAsyncTaskFunc = (obj) => _psuedoAsyncTask; private readonly TestHttp1Connection _http1Connection; - private (IDuplexPipe Transport, IDuplexPipe Application) _pair; + private DuplexPipe.DuplexPipePair _pair; private readonly byte[] _writeData; @@ -95,7 +95,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance { using (var memoryPool = new MemoryPool()) { - var pair = PipeFactory.CreateConnectionPair(memoryPool); + var pair = DuplexPipe.CreateConnectionPair(memoryPool); _pair = pair; var serviceContext = new ServiceContext diff --git a/benchmarks/Kestrel.Performance/HttpProtocolFeatureCollection.cs b/benchmarks/Kestrel.Performance/HttpProtocolFeatureCollection.cs index 23d9c80d3b..ddf7fa0554 100644 --- a/benchmarks/Kestrel.Performance/HttpProtocolFeatureCollection.cs +++ b/benchmarks/Kestrel.Performance/HttpProtocolFeatureCollection.cs @@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance public HttpProtocolFeatureCollection() { var memoryPool = new MemoryPool(); - var pair = PipeFactory.CreateConnectionPair(memoryPool); + var pair = DuplexPipe.CreateConnectionPair(memoryPool); var serviceContext = new ServiceContext { diff --git a/benchmarks/Kestrel.Performance/RequestParsingBenchmark.cs b/benchmarks/Kestrel.Performance/RequestParsingBenchmark.cs index 3c7d4caaf7..c682553483 100644 --- a/benchmarks/Kestrel.Performance/RequestParsingBenchmark.cs +++ b/benchmarks/Kestrel.Performance/RequestParsingBenchmark.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance public void Setup() { var memoryPool = new MemoryPool(); - var pair = PipeFactory.CreateConnectionPair(memoryPool); + var pair = DuplexPipe.CreateConnectionPair(memoryPool); var serviceContext = new ServiceContext { diff --git a/benchmarks/Kestrel.Performance/ResponseHeaderCollectionBenchmark.cs b/benchmarks/Kestrel.Performance/ResponseHeaderCollectionBenchmark.cs index 8f722aaba5..dd6cd25cf4 100644 --- a/benchmarks/Kestrel.Performance/ResponseHeaderCollectionBenchmark.cs +++ b/benchmarks/Kestrel.Performance/ResponseHeaderCollectionBenchmark.cs @@ -171,7 +171,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance public void Setup() { var memoryPool = new MemoryPool(); - var pair = PipeFactory.CreateConnectionPair(memoryPool); + var pair = DuplexPipe.CreateConnectionPair(memoryPool); var serviceContext = new ServiceContext { diff --git a/benchmarks/Kestrel.Performance/ResponseHeadersWritingBenchmark.cs b/benchmarks/Kestrel.Performance/ResponseHeadersWritingBenchmark.cs index 9c807620e4..8c7c3b46be 100644 --- a/benchmarks/Kestrel.Performance/ResponseHeadersWritingBenchmark.cs +++ b/benchmarks/Kestrel.Performance/ResponseHeadersWritingBenchmark.cs @@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance public void Setup() { var memoryPool = new MemoryPool(); - var pair = PipeFactory.CreateConnectionPair(memoryPool); + var pair = DuplexPipe.CreateConnectionPair(memoryPool); var serviceContext = new ServiceContext { diff --git a/src/Kestrel.Core/Internal/ConnectionHandler.cs b/src/Kestrel.Core/Internal/ConnectionHandler.cs index bf8b598866..41607602d4 100644 --- a/src/Kestrel.Core/Internal/ConnectionHandler.cs +++ b/src/Kestrel.Core/Internal/ConnectionHandler.cs @@ -36,10 +36,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal // REVIEW: Unfortunately, we still need to use the service context to create the pipes since the settings // for the scheduler and limits are specified here - var inputOptions = GetInputPipeOptions(_serviceContext, connectionContext.MemoryPool, transportFeature.InputWriterScheduler); - var outputOptions = GetOutputPipeOptions(_serviceContext, connectionContext.MemoryPool, transportFeature.OutputReaderScheduler); + var inputOptions = GetInputPipeOptions(_serviceContext, transportFeature.MemoryPool, transportFeature.InputWriterScheduler); + var outputOptions = GetOutputPipeOptions(_serviceContext, transportFeature.MemoryPool, transportFeature.OutputReaderScheduler); - var pair = PipeFactory.CreateConnectionPair(inputOptions, outputOptions); + var pair = DuplexPipe.CreateConnectionPair(inputOptions, outputOptions); // Set the transport and connection id connectionContext.ConnectionId = CorrelationIdGenerator.GetNextId(); diff --git a/src/Kestrel.Core/Internal/HttpConnectionMiddleware.cs b/src/Kestrel.Core/Internal/HttpConnectionMiddleware.cs index 6514768ab5..3e25712899 100644 --- a/src/Kestrel.Core/Internal/HttpConnectionMiddleware.cs +++ b/src/Kestrel.Core/Internal/HttpConnectionMiddleware.cs @@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal Protocols = _protocols, ServiceContext = _serviceContext, ConnectionFeatures = connectionContext.Features, - MemoryPool = connectionContext.MemoryPool, + MemoryPool = transportFeature.MemoryPool, ConnectionAdapters = _connectionAdapters, Transport = connectionContext.Transport, Application = transportFeature.Application diff --git a/src/Protocols.Abstractions/ConnectionContext.cs b/src/Protocols.Abstractions/ConnectionContext.cs index f4fb2dbae9..329afa4b11 100644 --- a/src/Protocols.Abstractions/ConnectionContext.cs +++ b/src/Protocols.Abstractions/ConnectionContext.cs @@ -1,8 +1,4 @@ -using System; -using System.Buffers; -using System.IO.Pipelines; -using System.Threading; -using System.Threading.Tasks; +using System.IO.Pipelines; using Microsoft.AspNetCore.Http.Features; namespace Microsoft.AspNetCore.Protocols @@ -14,7 +10,5 @@ namespace Microsoft.AspNetCore.Protocols public abstract IFeatureCollection Features { get; } public abstract IDuplexPipe Transport { get; set; } - - public abstract MemoryPool MemoryPool { get; } } } diff --git a/src/Protocols.Abstractions/DefaultConnectionContext.cs b/src/Protocols.Abstractions/DefaultConnectionContext.cs index 18ac26c673..cc75702caf 100644 --- a/src/Protocols.Abstractions/DefaultConnectionContext.cs +++ b/src/Protocols.Abstractions/DefaultConnectionContext.cs @@ -28,8 +28,6 @@ namespace Microsoft.AspNetCore.Protocols public override IFeatureCollection Features => _features.Collection; - public override MemoryPool MemoryPool => ConnectionTransportFeature.MemoryPool; - public override IDuplexPipe Transport { get => ConnectionTransportFeature.Transport; diff --git a/src/Protocols.Abstractions/DuplexPipe.cs b/src/Protocols.Abstractions/DuplexPipe.cs new file mode 100644 index 0000000000..a354af53e9 --- /dev/null +++ b/src/Protocols.Abstractions/DuplexPipe.cs @@ -0,0 +1,53 @@ +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Text; + +namespace System.IO.Pipelines +{ + public class DuplexPipe : IDuplexPipe + { + public DuplexPipe(PipeReader reader, PipeWriter writer) + { + Input = reader; + Output = writer; + } + + public PipeReader Input { get; } + + public PipeWriter Output { get; } + + public void Dispose() + { + } + + public static DuplexPipePair CreateConnectionPair(MemoryPool memoryPool) + { + return CreateConnectionPair(new PipeOptions(memoryPool), new PipeOptions(memoryPool)); + } + + public static DuplexPipePair CreateConnectionPair(PipeOptions inputOptions, PipeOptions outputOptions) + { + var input = new Pipe(inputOptions); + var output = new Pipe(outputOptions); + + var transportToApplication = new DuplexPipe(output.Reader, input.Writer); + var applicationToTransport = new DuplexPipe(input.Reader, output.Writer); + + return new DuplexPipePair(applicationToTransport, transportToApplication); + } + + // This class exists to work around issues with value tuple on .NET Framework + public readonly struct DuplexPipePair + { + public IDuplexPipe Transport { get; } + public IDuplexPipe Application { get; } + + public DuplexPipePair(IDuplexPipe transport, IDuplexPipe application) + { + Transport = transport; + Application = application; + } + } + } +} diff --git a/src/Protocols.Abstractions/PipeConnection.cs b/src/Protocols.Abstractions/PipeConnection.cs deleted file mode 100644 index 5b3ab2a50b..0000000000 --- a/src/Protocols.Abstractions/PipeConnection.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace System.IO.Pipelines -{ - public class PipeConnection : IDuplexPipe - { - public PipeConnection(PipeReader reader, PipeWriter writer) - { - Input = reader; - Output = writer; - } - - public PipeReader Input { get; } - - public PipeWriter Output { get; } - - public void Dispose() - { - } - } -} diff --git a/src/Protocols.Abstractions/PipeFactoryExtensions.cs b/src/Protocols.Abstractions/PipeFactoryExtensions.cs deleted file mode 100644 index 01abf37428..0000000000 --- a/src/Protocols.Abstractions/PipeFactoryExtensions.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Buffers; - -namespace System.IO.Pipelines -{ - public static class PipeFactory - { - public static (IDuplexPipe Transport, IDuplexPipe Application) CreateConnectionPair(MemoryPool memoryPool) - { - return CreateConnectionPair(new PipeOptions(memoryPool), new PipeOptions(memoryPool)); - } - - public static (IDuplexPipe Transport, IDuplexPipe Application) CreateConnectionPair(PipeOptions inputOptions, PipeOptions outputOptions) - { - var input = new Pipe(inputOptions); - var output = new Pipe(outputOptions); - - var transportToApplication = new PipeConnection(output.Reader, input.Writer); - var applicationToTransport = new PipeConnection(input.Reader, output.Writer); - - return (applicationToTransport, transportToApplication); - } - } -} diff --git a/test/Kestrel.Core.Tests/Http1ConnectionTests.cs b/test/Kestrel.Core.Tests/Http1ConnectionTests.cs index de20cc3f1e..7e286aad82 100644 --- a/test/Kestrel.Core.Tests/Http1ConnectionTests.cs +++ b/test/Kestrel.Core.Tests/Http1ConnectionTests.cs @@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests public Http1ConnectionTests() { _pipelineFactory = new MemoryPool(); - var pair = PipeFactory.CreateConnectionPair(_pipelineFactory); + var pair = DuplexPipe.CreateConnectionPair(_pipelineFactory); _transport = pair.Transport; _application = pair.Application; diff --git a/test/Kestrel.Core.Tests/Http2ConnectionTests.cs b/test/Kestrel.Core.Tests/Http2ConnectionTests.cs index 9ab55bc8d5..e88add0081 100644 --- a/test/Kestrel.Core.Tests/Http2ConnectionTests.cs +++ b/test/Kestrel.Core.Tests/Http2ConnectionTests.cs @@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests private static readonly byte[] _maxData = Encoding.ASCII.GetBytes(new string('a', Http2Frame.MinAllowedMaxFrameSize)); private readonly MemoryPool _memoryPool = new MemoryPool(); - private readonly (IDuplexPipe Transport, IDuplexPipe Application) _pair; + private readonly DuplexPipe.DuplexPipePair _pair; private readonly TestApplicationErrorLogger _logger; private readonly Http2ConnectionContext _connectionContext; private readonly Http2Connection _connection; @@ -122,7 +122,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests public Http2ConnectionTests() { - _pair = PipeFactory.CreateConnectionPair(_memoryPool); + _pair = DuplexPipe.CreateConnectionPair(_memoryPool); _noopApplication = context => Task.CompletedTask; diff --git a/test/Kestrel.Core.Tests/HttpConnectionTests.cs b/test/Kestrel.Core.Tests/HttpConnectionTests.cs index e426c22d21..4e2829e863 100644 --- a/test/Kestrel.Core.Tests/HttpConnectionTests.cs +++ b/test/Kestrel.Core.Tests/HttpConnectionTests.cs @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests public HttpConnectionTests() { _memoryPool = new MemoryPool(); - var pair = PipeFactory.CreateConnectionPair(_memoryPool); + var pair = DuplexPipe.CreateConnectionPair(_memoryPool); _httpConnectionContext = new HttpConnectionContext { diff --git a/test/Kestrel.Core.Tests/HttpResponseHeadersTests.cs b/test/Kestrel.Core.Tests/HttpResponseHeadersTests.cs index 4634b758cf..0df993ab89 100644 --- a/test/Kestrel.Core.Tests/HttpResponseHeadersTests.cs +++ b/test/Kestrel.Core.Tests/HttpResponseHeadersTests.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests { using (var memoryPool = new MemoryPool()) { - var pair = PipeFactory.CreateConnectionPair(memoryPool); + var pair = DuplexPipe.CreateConnectionPair(memoryPool); var http1ConnectionContext = new Http1ConnectionContext { ServiceContext = new TestServiceContext(), diff --git a/test/Kestrel.Core.Tests/TestInput.cs b/test/Kestrel.Core.Tests/TestInput.cs index 6153e8d2a5..601fcd133e 100644 --- a/test/Kestrel.Core.Tests/TestInput.cs +++ b/test/Kestrel.Core.Tests/TestInput.cs @@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests public TestInput() { _memoryPool = new MemoryPool(); - var pair = PipeFactory.CreateConnectionPair(_memoryPool); + var pair = DuplexPipe.CreateConnectionPair(_memoryPool); Transport = pair.Transport; Application = pair.Application; diff --git a/test/Kestrel.Transport.Libuv.Tests/LibuvOutputConsumerTests.cs b/test/Kestrel.Transport.Libuv.Tests/LibuvOutputConsumerTests.cs index a63ab1bec8..d674ae6e96 100644 --- a/test/Kestrel.Transport.Libuv.Tests/LibuvOutputConsumerTests.cs +++ b/test/Kestrel.Transport.Libuv.Tests/LibuvOutputConsumerTests.cs @@ -695,7 +695,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests private Http1OutputProducer CreateOutputProducer(PipeOptions pipeOptions, CancellationTokenSource cts = null) { - var pair = PipeFactory.CreateConnectionPair(pipeOptions, pipeOptions); + var pair = DuplexPipe.CreateConnectionPair(pipeOptions, pipeOptions); var logger = new TestApplicationErrorLogger(); var serviceContext = new TestServiceContext diff --git a/test/Kestrel.Transport.Libuv.Tests/TestHelpers/MockConnectionHandler.cs b/test/Kestrel.Transport.Libuv.Tests/TestHelpers/MockConnectionHandler.cs index d52a868b67..2b2b380755 100644 --- a/test/Kestrel.Transport.Libuv.Tests/TestHelpers/MockConnectionHandler.cs +++ b/test/Kestrel.Transport.Libuv.Tests/TestHelpers/MockConnectionHandler.cs @@ -20,13 +20,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests.TestHelpers { var connectionContext = new DefaultConnectionContext(features); - Input = new Pipe(InputOptions(connectionContext.MemoryPool)); - Output = new Pipe(OutputOptions(connectionContext.MemoryPool)); - var feature = connectionContext.Features.Get(); - connectionContext.Transport = new PipeConnection(Input.Reader, Output.Writer); - feature.Application = new PipeConnection(Output.Reader, Input.Writer); + Input = new Pipe(InputOptions(feature.MemoryPool)); + Output = new Pipe(OutputOptions(feature.MemoryPool)); + + connectionContext.Transport = new DuplexPipe(Input.Reader, Output.Writer); + feature.Application = new DuplexPipe(Output.Reader, Input.Writer); } public Pipe Input { get; private set; }