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:
parent
a37fa83aee
commit
6b183c5ac0
|
|
@ -3,15 +3,16 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Pipelines;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
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
|
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal
|
||||||
{
|
{
|
||||||
public class AdaptedPipeline : IDuplexPipe
|
public class AdaptedPipeline : IDuplexPipe
|
||||||
{
|
{
|
||||||
private const int MinAllocBufferSize = 2048;
|
private static readonly int MinAllocBufferSize = KestrelMemoryPool.MinimumSegmentSize / 2;
|
||||||
|
|
||||||
private readonly IDuplexPipe _transport;
|
private readonly IDuplexPipe _transport;
|
||||||
private readonly IDuplexPipe _application;
|
private readonly IDuplexPipe _application;
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
writerScheduler: writerScheduler,
|
writerScheduler: writerScheduler,
|
||||||
pauseWriterThreshold: serviceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0,
|
pauseWriterThreshold: serviceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0,
|
||||||
resumeWriterThreshold: 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
|
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,
|
writerScheduler: serviceContext.Scheduler,
|
||||||
pauseWriterThreshold: GetOutputResponseBufferSize(serviceContext),
|
pauseWriterThreshold: GetOutputResponseBufferSize(serviceContext),
|
||||||
resumeWriterThreshold: GetOutputResponseBufferSize(serviceContext),
|
resumeWriterThreshold: GetOutputResponseBufferSize(serviceContext),
|
||||||
useSynchronizationContext: false
|
useSynchronizationContext: false,
|
||||||
|
minimumSegmentSize: KestrelMemoryPool.MinimumSegmentSize
|
||||||
);
|
);
|
||||||
|
|
||||||
private static long GetOutputResponseBufferSize(ServiceContext serviceContext)
|
private static long GetOutputResponseBufferSize(ServiceContext serviceContext)
|
||||||
|
|
@ -13,11 +13,12 @@ using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Connections;
|
||||||
using Microsoft.AspNetCore.Hosting.Server;
|
using Microsoft.AspNetCore.Hosting.Server;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
using Microsoft.AspNetCore.Connections;
|
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
|
|
||||||
|
|
@ -1340,7 +1341,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
writerScheduler: PipeScheduler.Inline,
|
writerScheduler: PipeScheduler.Inline,
|
||||||
pauseWriterThreshold: 1,
|
pauseWriterThreshold: 1,
|
||||||
resumeWriterThreshold: 1,
|
resumeWriterThreshold: 1,
|
||||||
useSynchronizationContext: false
|
useSynchronizationContext: false,
|
||||||
|
minimumSegmentSize: KestrelMemoryPool.MinimumSegmentSize
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
|
|
@ -78,7 +79,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
writerScheduler: PipeScheduler.Inline,
|
writerScheduler: PipeScheduler.Inline,
|
||||||
pauseWriterThreshold: _context.ServiceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0,
|
pauseWriterThreshold: _context.ServiceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0,
|
||||||
resumeWriterThreshold: _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
|
internal PipeOptions AdaptedOutputPipeOptions => new PipeOptions
|
||||||
|
|
@ -88,7 +90,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
writerScheduler: PipeScheduler.Inline,
|
writerScheduler: PipeScheduler.Inline,
|
||||||
pauseWriterThreshold: _context.ServiceContext.ServerOptions.Limits.MaxResponseBufferSize ?? 0,
|
pauseWriterThreshold: _context.ServiceContext.ServerOptions.Limits.MaxResponseBufferSize ?? 0,
|
||||||
resumeWriterThreshold: _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;
|
private IKestrelTrace Log => _context.ServiceContext.Log;
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal
|
||||||
public static class KestrelMemoryPool
|
public static class KestrelMemoryPool
|
||||||
{
|
{
|
||||||
public static MemoryPool<byte> Create() => new SlabMemoryPool();
|
public static MemoryPool<byte> Create() => new SlabMemoryPool();
|
||||||
|
|
||||||
|
public static readonly int MinimumSegmentSize = 4096;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal
|
||||||
{
|
{
|
||||||
public partial class LibuvConnection : LibuvConnectionContext
|
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 =
|
private static readonly Action<UvStreamHandle, int, object> _readCallback =
|
||||||
(handle, status, state) => ReadCallback(handle, status, state);
|
(handle, status, state) => ReadCallback(handle, status, state);
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
|
||||||
{
|
{
|
||||||
internal sealed class SocketConnection : TransportConnection
|
internal sealed class SocketConnection : TransportConnection
|
||||||
{
|
{
|
||||||
private const int MinAllocBufferSize = 2048;
|
private static readonly int MinAllocBufferSize = KestrelMemoryPool.MinimumSegmentSize / 2;
|
||||||
public readonly static bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||||
|
|
||||||
private readonly Socket _socket;
|
private readonly Socket _socket;
|
||||||
private readonly PipeScheduler _scheduler;
|
private readonly PipeScheduler _scheduler;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue