From 8f0d1179ab8cc636febd8a319ba14008d96d037d Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Mon, 19 Oct 2015 12:44:21 -0700 Subject: [PATCH] =?UTF-8?q?Allow=20Nagle=E2=80=99s=20algorithm=20to=20be?= =?UTF-8?q?=20disabled=20via=20IKestrelServerInformation.NoDelay?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- samples/SampleApp/Startup.cs | 1 + src/Microsoft.AspNet.Server.Kestrel/Http/TcpListener.cs | 2 ++ .../Http/TcpListenerPrimary.cs | 2 ++ .../Http/TcpListenerSecondary.cs | 1 + .../IKestrelServerInformation.cs | 2 ++ .../KestrelServerInformation.cs | 2 ++ src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs | 9 +++++++++ .../Networking/UvTcpHandle.cs | 5 +++++ src/Microsoft.AspNet.Server.Kestrel/ServerFactory.cs | 3 ++- src/Microsoft.AspNet.Server.Kestrel/ServiceContext.cs | 3 +++ 10 files changed, 29 insertions(+), 1 deletion(-) diff --git a/samples/SampleApp/Startup.cs b/samples/SampleApp/Startup.cs index 834aadd1d1..7b863a5624 100644 --- a/samples/SampleApp/Startup.cs +++ b/samples/SampleApp/Startup.cs @@ -23,6 +23,7 @@ namespace SampleApp { var ksi = app.ServerFeatures.Get(); //ksi.ThreadCount = 4; + ksi.NoDelay = true; loggerFactory.MinimumLevel = LogLevel.Debug; diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListener.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListener.cs index b09d86a43c..d3af771f5d 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListener.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListener.cs @@ -25,6 +25,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { var socket = new UvTcpHandle(Log); socket.Init(Thread.Loop, Thread.QueueCloseHandle); + socket.NoDelay(NoDelay); socket.Bind(ServerAddress); socket.Listen(Constants.ListenBacklog, ConnectionCallback, this); return socket; @@ -39,6 +40,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { var acceptSocket = new UvTcpHandle(Log); acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle); + acceptSocket.NoDelay(NoDelay); try { diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListenerPrimary.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListenerPrimary.cs index 700e888195..4f1ff0a48d 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListenerPrimary.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListenerPrimary.cs @@ -25,6 +25,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { var socket = new UvTcpHandle(Log); socket.Init(Thread.Loop, Thread.QueueCloseHandle); + socket.NoDelay(NoDelay); socket.Bind(ServerAddress); socket.Listen(Constants.ListenBacklog, ConnectionCallback, this); return socket; @@ -39,6 +40,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { var acceptSocket = new UvTcpHandle(Log); acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle); + acceptSocket.NoDelay(NoDelay); try { diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListenerSecondary.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListenerSecondary.cs index d6680d3318..9a36f2b171 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListenerSecondary.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/TcpListenerSecondary.cs @@ -21,6 +21,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { var acceptSocket = new UvTcpHandle(Log); acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle); + acceptSocket.NoDelay(NoDelay); return acceptSocket; } } diff --git a/src/Microsoft.AspNet.Server.Kestrel/IKestrelServerInformation.cs b/src/Microsoft.AspNet.Server.Kestrel/IKestrelServerInformation.cs index 5e90ebdfc7..870fe2e533 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/IKestrelServerInformation.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/IKestrelServerInformation.cs @@ -9,6 +9,8 @@ namespace Microsoft.AspNet.Server.Kestrel { int ThreadCount { get; set; } + bool NoDelay { get; set; } + IConnectionFilter ConnectionFilter { get; set; } } } diff --git a/src/Microsoft.AspNet.Server.Kestrel/KestrelServerInformation.cs b/src/Microsoft.AspNet.Server.Kestrel/KestrelServerInformation.cs index 3f50057c5d..840533012c 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/KestrelServerInformation.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/KestrelServerInformation.cs @@ -15,6 +15,8 @@ namespace Microsoft.AspNet.Server.Kestrel public int ThreadCount { get; set; } + public bool NoDelay { get; set; } + public IConnectionFilter ConnectionFilter { get; set; } public void Initialize(IConfiguration configuration) diff --git a/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs b/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs index f926b16bd5..a94d954a07 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Networking/Libuv.cs @@ -202,6 +202,15 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking Check(_uv_tcp_open(handle, hSocket)); } + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + protected delegate int uv_tcp_nodelay(UvTcpHandle handle, int enable); + protected uv_tcp_nodelay _uv_tcp_nodelay = default(uv_tcp_nodelay); + public void tcp_nodelay(UvTcpHandle handle, bool enable) + { + handle.Validate(); + Check(_uv_tcp_nodelay(handle, enable ? 1 : 0)); + } + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] protected delegate int uv_pipe_init(UvLoopHandle loop, UvPipeHandle handle, int ipc); protected uv_pipe_init _uv_pipe_init = default(uv_pipe_init); diff --git a/src/Microsoft.AspNet.Server.Kestrel/Networking/UvTcpHandle.cs b/src/Microsoft.AspNet.Server.Kestrel/Networking/UvTcpHandle.cs index 4e79ea9864..b43e9c985e 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Networking/UvTcpHandle.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Networking/UvTcpHandle.cs @@ -61,6 +61,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking _uv.tcp_open(this, hSocket); } + public void NoDelay(bool enable) + { + _uv.tcp_nodelay(this, enable); + } + /// /// Returns an for the given host an port. /// If the host parameter isn't "localhost" or an IP address, use IPAddress.Any. diff --git a/src/Microsoft.AspNet.Server.Kestrel/ServerFactory.cs b/src/Microsoft.AspNet.Server.Kestrel/ServerFactory.cs index 2abaf71ecf..f39bff2a27 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/ServerFactory.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/ServerFactory.cs @@ -61,7 +61,8 @@ namespace Microsoft.AspNet.Server.Kestrel AppLifetime = _appLifetime, Log = new KestrelTrace(_logger), DateHeaderValueManager = dateHeaderValueManager, - ConnectionFilter = information.ConnectionFilter + ConnectionFilter = information.ConnectionFilter, + NoDelay = information.NoDelay }); disposables.Push(engine); diff --git a/src/Microsoft.AspNet.Server.Kestrel/ServiceContext.cs b/src/Microsoft.AspNet.Server.Kestrel/ServiceContext.cs index b777101539..35086de40d 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/ServiceContext.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/ServiceContext.cs @@ -22,6 +22,7 @@ namespace Microsoft.AspNet.Server.Kestrel Log = context.Log; DateHeaderValueManager = context.DateHeaderValueManager; ConnectionFilter = context.ConnectionFilter; + NoDelay = context.NoDelay; } public IApplicationLifetime AppLifetime { get; set; } @@ -33,5 +34,7 @@ namespace Microsoft.AspNet.Server.Kestrel public DateHeaderValueManager DateHeaderValueManager { get; set; } public IConnectionFilter ConnectionFilter { get; set; } + + public bool NoDelay { get; set; } } }