From 5eaa7e51c868e2b89f9c7dff4701af22ae98f0d0 Mon Sep 17 00:00:00 2001 From: Kristian Hellang Date: Mon, 23 Nov 2015 00:05:10 +0100 Subject: [PATCH] Initialize ThreadCount as early as possible This will allow you to inspect the property in the Configure method. Closes #404 --- .../KestrelServer.cs | 31 +++---------------- .../KestrelServerInformation.cs | 24 ++++++++++---- .../ServerFactory.cs | 29 +++++++++++++++-- 3 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/Microsoft.AspNet.Server.Kestrel/KestrelServer.cs b/src/Microsoft.AspNet.Server.Kestrel/KestrelServer.cs index b8e9c5dd07..3a1295de76 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/KestrelServer.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/KestrelServer.cs @@ -73,34 +73,13 @@ namespace Microsoft.AspNet.Server.Kestrel _disposables.Push(engine); _disposables.Push(dateHeaderValueManager); - // Actual core count would be a better number - // rather than logical cores which includes hyper-threaded cores. - // Divide by 2 for hyper-threading, and good defaults (still need threads to do webserving). - // Can be user overriden using IKestrelServerInformation.ThreadCount - var threadCount = Environment.ProcessorCount >> 1; + var threadCount = information.ThreadCount; - if (threadCount < 1) + if (threadCount <= 0) { - // Ensure shifted value is at least one - threadCount = 1; - } - else if (threadCount > 16) - { - // Receive Side Scaling RSS Processor count currently maxes out at 16 - // would be better to check the NIC's current hardware queues; but xplat... - threadCount = 16; - } - - if (information.ThreadCount < 0) - { - throw new ArgumentOutOfRangeException(nameof(information.ThreadCount), - information.ThreadCount, - "ThreadCount cannot be negative"); - } - else if (information.ThreadCount > 0) - { - // ThreadCount has been user set, use that value - threadCount = information.ThreadCount; + throw new ArgumentOutOfRangeException(nameof(threadCount), + threadCount, + "ThreadCount must be positive."); } engine.Start(threadCount); diff --git a/src/Microsoft.AspNet.Server.Kestrel/KestrelServerInformation.cs b/src/Microsoft.AspNet.Server.Kestrel/KestrelServerInformation.cs index 71e6ababcf..ec31f4fbf6 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/KestrelServerInformation.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/KestrelServerInformation.cs @@ -11,21 +11,33 @@ namespace Microsoft.AspNet.Server.Kestrel { public class KestrelServerInformation : IKestrelServerInformation, IServerAddressesFeature { - public ICollection Addresses { get; } = new List(); + public KestrelServerInformation(IConfiguration configuration, int threadCount) + { + Addresses = GetAddresses(configuration); + ThreadCount = threadCount; + NoDelay = true; + } + + public ICollection Addresses { get; } public int ThreadCount { get; set; } - public bool NoDelay { get; set; } = true; + public bool NoDelay { get; set; } public IConnectionFilter ConnectionFilter { get; set; } - public void Initialize(IConfiguration configuration) + private static ICollection GetAddresses(IConfiguration configuration) { - var urls = configuration["server.urls"] ?? string.Empty; - foreach (var url in urls.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) + var addresses = new List(); + + var urls = configuration["server.urls"]; + + if (!string.IsNullOrEmpty(urls)) { - Addresses.Add(url); + addresses.AddRange(urls.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)); } + + return addresses; } } } diff --git a/src/Microsoft.AspNet.Server.Kestrel/ServerFactory.cs b/src/Microsoft.AspNet.Server.Kestrel/ServerFactory.cs index ccde5797ce..284823b849 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/ServerFactory.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/ServerFactory.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Hosting.Server; using Microsoft.AspNet.Http.Features; @@ -26,12 +27,36 @@ namespace Microsoft.AspNet.Server.Kestrel public IServer CreateServer(IConfiguration configuration) { - var information = new KestrelServerInformation(); - information.Initialize(configuration); + var threadCount = GetThreadCount(); + var information = new KestrelServerInformation(configuration, threadCount); var serverFeatures = new FeatureCollection(); serverFeatures.Set(information); serverFeatures.Set(information); return new KestrelServer(serverFeatures, _appLifetime, _loggerFactory.CreateLogger("Microsoft.AspNet.Server.Kestrel")); } + + private static int GetThreadCount() + { + // Actual core count would be a better number + // rather than logical cores which includes hyper-threaded cores. + // Divide by 2 for hyper-threading, and good defaults (still need threads to do webserving). + // Can be user overriden using IKestrelServerInformation.ThreadCount + var threadCount = Environment.ProcessorCount >> 1; + + if (threadCount < 1) + { + // Ensure shifted value is at least one + return 1; + } + + if (threadCount > 16) + { + // Receive Side Scaling RSS Processor count currently maxes out at 16 + // would be better to check the NIC's current hardware queues; but xplat... + return 16; + } + + return threadCount; + } } }