Add inline scheduler option for Sockets transport (#24638)
This commit is contained in:
parent
512a49c401
commit
c92eaa28f4
|
|
@ -63,7 +63,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets
|
|||
_trace,
|
||||
_options.MaxReadBufferSize,
|
||||
_options.MaxWriteBufferSize,
|
||||
_options.WaitForDataBeforeAllocatingBuffer);
|
||||
_options.WaitForDataBeforeAllocatingBuffer,
|
||||
_options.UnsafePreferInlineScheduling);
|
||||
|
||||
socketConnection.Start();
|
||||
return socketConnection;
|
||||
|
|
|
|||
|
|
@ -37,11 +37,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
|
|||
|
||||
internal SocketConnection(Socket socket,
|
||||
MemoryPool<byte> memoryPool,
|
||||
PipeScheduler scheduler,
|
||||
PipeScheduler transportScheduler,
|
||||
ISocketsTrace trace,
|
||||
long? maxReadBufferSize = null,
|
||||
long? maxWriteBufferSize = null,
|
||||
bool waitForData = true)
|
||||
bool waitForData = true,
|
||||
bool useInlineSchedulers = false)
|
||||
{
|
||||
Debug.Assert(socket != null);
|
||||
Debug.Assert(memoryPool != null);
|
||||
|
|
@ -60,7 +61,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
|
|||
// On *nix platforms, Sockets already dispatches to the ThreadPool.
|
||||
// Yes, the IOQueues are still used for the PipeSchedulers. This is intentional.
|
||||
// https://github.com/aspnet/KestrelHttpServer/issues/2573
|
||||
var awaiterScheduler = IsWindows ? scheduler : PipeScheduler.Inline;
|
||||
var awaiterScheduler = IsWindows ? transportScheduler : PipeScheduler.Inline;
|
||||
|
||||
var applicationScheduler = PipeScheduler.ThreadPool;
|
||||
if (useInlineSchedulers)
|
||||
{
|
||||
transportScheduler = PipeScheduler.Inline;
|
||||
awaiterScheduler = PipeScheduler.Inline;
|
||||
applicationScheduler = PipeScheduler.Inline;
|
||||
}
|
||||
|
||||
_receiver = new SocketReceiver(_socket, awaiterScheduler);
|
||||
_sender = new SocketSender(_socket, awaiterScheduler);
|
||||
|
|
@ -68,8 +77,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
|
|||
maxReadBufferSize ??= 0;
|
||||
maxWriteBufferSize ??= 0;
|
||||
|
||||
var inputOptions = new PipeOptions(MemoryPool, PipeScheduler.ThreadPool, scheduler, maxReadBufferSize.Value, maxReadBufferSize.Value / 2, useSynchronizationContext: false);
|
||||
var outputOptions = new PipeOptions(MemoryPool, scheduler, PipeScheduler.ThreadPool, maxWriteBufferSize.Value, maxWriteBufferSize.Value / 2, useSynchronizationContext: false);
|
||||
var inputOptions = new PipeOptions(MemoryPool, applicationScheduler, transportScheduler, maxReadBufferSize.Value, maxReadBufferSize.Value / 2, useSynchronizationContext: false);
|
||||
var outputOptions = new PipeOptions(MemoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize.Value, maxWriteBufferSize.Value / 2, useSynchronizationContext: false);
|
||||
|
||||
var pair = DuplexPipe.CreateConnectionPair(inputOptions, outputOptions);
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets
|
|||
}
|
||||
|
||||
var connection = new SocketConnection(acceptSocket, _memoryPool, _schedulers[_schedulerIndex], _trace,
|
||||
_options.MaxReadBufferSize, _options.MaxWriteBufferSize, _options.WaitForDataBeforeAllocatingBuffer);
|
||||
_options.MaxReadBufferSize, _options.MaxWriteBufferSize, _options.WaitForDataBeforeAllocatingBuffer,
|
||||
_options.UnsafePreferInlineScheduling);
|
||||
|
||||
connection.Start();
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets
|
|||
|
||||
public long? MaxWriteBufferSize { get; set; } = 64 * 1024;
|
||||
|
||||
/// <summary>
|
||||
/// Inline application and transport continuations instead of dispatching to the threadpool.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This will run application code on the IO thread which is why this is unsafe.
|
||||
/// It is recommended to set the DOTNET_SYSTEM_NET_SOCKETS_INLINE_COMPLETIONS environment variable to '1' when using this setting to also inline the completions
|
||||
/// at the runtime layer as well.
|
||||
/// This setting can make performance worse if there is expensive work that will end up holding onto the IO thread for longer than needed.
|
||||
/// Test to make sure this setting helps performance.
|
||||
/// </remarks>
|
||||
public bool UnsafePreferInlineScheduling { get; set; }
|
||||
|
||||
internal Func<MemoryPool<byte>> MemoryPoolFactory { get; set; } = System.Buffers.SlabMemoryPoolFactory.Create;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue