Use 4K as the minimum segment size (#2452)

- This normalizes the behavior for kestrel no matter what memory pool implementation is used. The transports should behave the same (ask for 1/2 full blocks) across pool implementations.
- Declare the minimum segment size in KestrelMemoryPool
- Updated the AdaptedPipeline to use MinimumSegmentSize / 2
This commit is contained in:
David Fowler 2018-04-02 16:14:40 -07:00 committed by GitHub
parent a37fa83aee
commit 6b183c5ac0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 21 additions and 11 deletions

View File

@ -3,15 +3,16 @@
using System;
using System.IO;
using System.IO.Pipelines;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using System.IO.Pipelines;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal
{
public class AdaptedPipeline : IDuplexPipe
{
private const int MinAllocBufferSize = 2048;
private static readonly int MinAllocBufferSize = KestrelMemoryPool.MinimumSegmentSize / 2;
private readonly IDuplexPipe _transport;
private readonly IDuplexPipe _application;

View File

@ -86,7 +86,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
writerScheduler: writerScheduler,
pauseWriterThreshold: serviceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0,
resumeWriterThreshold: serviceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0,
useSynchronizationContext: false
useSynchronizationContext: false,
minimumSegmentSize: KestrelMemoryPool.MinimumSegmentSize
);
internal static PipeOptions GetOutputPipeOptions(ServiceContext serviceContext, MemoryPool<byte> memoryPool, PipeScheduler readerScheduler) => new PipeOptions
@ -96,7 +97,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
writerScheduler: serviceContext.Scheduler,
pauseWriterThreshold: GetOutputResponseBufferSize(serviceContext),
resumeWriterThreshold: GetOutputResponseBufferSize(serviceContext),
useSynchronizationContext: false
useSynchronizationContext: false,
minimumSegmentSize: KestrelMemoryPool.MinimumSegmentSize
);
private static long GetOutputResponseBufferSize(ServiceContext serviceContext)

View File

@ -13,11 +13,12 @@ using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
@ -1340,7 +1341,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
writerScheduler: PipeScheduler.Inline,
pauseWriterThreshold: 1,
resumeWriterThreshold: 1,
useSynchronizationContext: false
useSynchronizationContext: false,
minimumSegmentSize: KestrelMemoryPool.MinimumSegmentSize
));
}
}

View File

@ -17,6 +17,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Features;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
@ -78,7 +79,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
writerScheduler: PipeScheduler.Inline,
pauseWriterThreshold: _context.ServiceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0,
resumeWriterThreshold: _context.ServiceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0,
useSynchronizationContext: false
useSynchronizationContext: false,
minimumSegmentSize: KestrelMemoryPool.MinimumSegmentSize
);
internal PipeOptions AdaptedOutputPipeOptions => new PipeOptions
@ -88,7 +90,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
writerScheduler: PipeScheduler.Inline,
pauseWriterThreshold: _context.ServiceContext.ServerOptions.Limits.MaxResponseBufferSize ?? 0,
resumeWriterThreshold: _context.ServiceContext.ServerOptions.Limits.MaxResponseBufferSize ?? 0,
useSynchronizationContext: false
useSynchronizationContext: false,
minimumSegmentSize: KestrelMemoryPool.MinimumSegmentSize
);
private IKestrelTrace Log => _context.ServiceContext.Log;

View File

@ -8,5 +8,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal
public static class KestrelMemoryPool
{
public static MemoryPool<byte> Create() => new SlabMemoryPool();
public static readonly int MinimumSegmentSize = 4096;
}
}

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal
{
public partial class LibuvConnection : LibuvConnectionContext
{
private const int MinAllocBufferSize = 2048;
private static readonly int MinAllocBufferSize = KestrelMemoryPool.MinimumSegmentSize / 2;
private static readonly Action<UvStreamHandle, int, object> _readCallback =
(handle, status, state) => ReadCallback(handle, status, state);

View File

@ -18,8 +18,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
{
internal sealed class SocketConnection : TransportConnection
{
private const int MinAllocBufferSize = 2048;
public readonly static bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
private static readonly int MinAllocBufferSize = KestrelMemoryPool.MinimumSegmentSize / 2;
private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
private readonly Socket _socket;
private readonly PipeScheduler _scheduler;