From 3b227d100999d3884847584cf1124b322379d470 Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Tue, 19 Sep 2023 14:34:02 -0700 Subject: [PATCH 01/11] Skipping native placeholder specialization if host is not 64 bit process --- src/WebJobs.Script/Environment/IEnvironment.cs | 7 ++++++- src/WebJobs.Script/Environment/SystemEnvironment.cs | 2 ++ .../Workers/Rpc/WebHostRpcWorkerChannelManager.cs | 9 +++++++++ test/WebJobs.Script.Tests.Shared/TestEnvironment.cs | 13 +++++++++++-- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/WebJobs.Script/Environment/IEnvironment.cs b/src/WebJobs.Script/Environment/IEnvironment.cs index 2889e3b7e2..e502b8effd 100644 --- a/src/WebJobs.Script/Environment/IEnvironment.cs +++ b/src/WebJobs.Script/Environment/IEnvironment.cs @@ -12,6 +12,11 @@ namespace Microsoft.Azure.WebJobs.Script /// public interface IEnvironment { + /// + /// Gets a value indicating whether the current process is a 64-bit process. + /// + public bool Is64BitProcess { get; } + /// /// Returns the value of an environment variable for the current . /// @@ -20,7 +25,7 @@ public interface IEnvironment string GetEnvironmentVariable(string name); /// - /// Creates, modifies, or deletes an environment variable stored in the current + /// Creates, modifies, or deletes an environment variable stored in the current . /// /// The environment variable name. /// The value to assign to the variable. diff --git a/src/WebJobs.Script/Environment/SystemEnvironment.cs b/src/WebJobs.Script/Environment/SystemEnvironment.cs index ed3e862225..d8ac86e36a 100644 --- a/src/WebJobs.Script/Environment/SystemEnvironment.cs +++ b/src/WebJobs.Script/Environment/SystemEnvironment.cs @@ -17,6 +17,8 @@ private SystemEnvironment() public static SystemEnvironment Instance => _instance.Value; + public bool Is64BitProcess => Environment.Is64BitProcess; + private static SystemEnvironment CreateInstance() { return new SystemEnvironment(); diff --git a/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs b/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs index af2863f7cc..745b14f464 100644 --- a/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs +++ b/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs @@ -181,6 +181,15 @@ private bool UsePlaceholderChannel(IRpcWorkerChannel channel) return false; } + // We support specialization of dotnet-isolated only on 64bit host process. + var is64Bit = _environment.Is64BitProcess; + _logger.LogDebug("Is64BitProcess: {is64Bit}", is64Bit.ToString()); + + if (!is64Bit) + { + return false; + } + // Do not specialize if the placeholder is 6.0 but the site is 7.0 (for example). var currentWorkerRuntimeVersion = _environment.GetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeVersionSettingName); channel.WorkerProcess.Process.StartInfo.Environment.TryGetValue(RpcWorkerConstants.FunctionWorkerRuntimeVersionSettingName, out string placeholderWorkerRuntimeVersion); diff --git a/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs b/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs index 1bd73bea94..649b417a91 100644 --- a/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs +++ b/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs @@ -12,15 +12,24 @@ namespace Microsoft.Azure.WebJobs.Script.Tests public class TestEnvironment : IEnvironment { private readonly IDictionary _variables; + private bool _is64BitProcess; + + public bool Is64BitProcess => _is64BitProcess; public TestEnvironment() - : this(new Dictionary()) + : this(new Dictionary()) + { + } + + public TestEnvironment(IDictionary variables) + : this(variables, is64BitProcess: true) { } - public TestEnvironment(IDictionary variables) + public TestEnvironment(IDictionary variables, bool is64BitProcess) { _variables = variables ?? throw new ArgumentNullException(nameof(variables)); + _is64BitProcess = is64BitProcess; } public void Clear() From 3d3152794e022177958d23b6ca70023ee4f693e9 Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Tue, 19 Sep 2023 15:02:26 -0700 Subject: [PATCH 02/11] formatting linting fix --- .../ExtensionBundle/ExtensionBundleManager.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/WebJobs.Script/ExtensionBundle/ExtensionBundleManager.cs b/src/WebJobs.Script/ExtensionBundle/ExtensionBundleManager.cs index afd3563a3a..3c88df31f3 100644 --- a/src/WebJobs.Script/ExtensionBundle/ExtensionBundleManager.cs +++ b/src/WebJobs.Script/ExtensionBundle/ExtensionBundleManager.cs @@ -71,7 +71,7 @@ public bool IsLegacyExtensionBundle() /// /// Attempts to locate the extension bundle inside the probing paths and download paths. If the extension bundle is not found then it will download the extension bundle. /// - /// Path of the extension bundle + /// Path of the extension bundle. public async Task GetExtensionBundlePath() { using (var httpClient = new HttpClient()) @@ -83,8 +83,8 @@ public async Task GetExtensionBundlePath() /// /// Attempts to locate the extension bundle inside the probing paths and download paths. If the extension bundle is not found then it will download the extension bundle. /// - /// HttpClient used to download the extension bundle - /// Path of the extension bundle + /// HttpClient used to download the extension bundle. + /// Path of the extension bundle. public async Task GetExtensionBundlePath(HttpClient httpClient) { return await GetBundle(httpClient); From 8e232f1d3521c34ed9a0de3b95634b987b8c12f4 Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Tue, 19 Sep 2023 15:21:51 -0700 Subject: [PATCH 03/11] Stylecop fix. --- test/WebJobs.Script.Tests.Shared/TestEnvironment.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs b/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs index 649b417a91..41672c89e4 100644 --- a/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs +++ b/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs @@ -14,8 +14,6 @@ public class TestEnvironment : IEnvironment private readonly IDictionary _variables; private bool _is64BitProcess; - public bool Is64BitProcess => _is64BitProcess; - public TestEnvironment() : this(new Dictionary()) { @@ -32,6 +30,8 @@ public TestEnvironment(IDictionary variables, bool is64BitProces _is64BitProcess = is64BitProcess; } + public bool Is64BitProcess => _is64BitProcess; + public void Clear() { _variables.Clear(); From 046bec3fbcf09f3a4ea5f575e3f9b14070bfa681 Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Tue, 19 Sep 2023 15:22:56 -0700 Subject: [PATCH 04/11] fix indentation --- test/WebJobs.Script.Tests.Shared/TestEnvironment.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs b/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs index 41672c89e4..e819f5ec83 100644 --- a/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs +++ b/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs @@ -19,7 +19,7 @@ public TestEnvironment() { } - public TestEnvironment(IDictionary variables) + public TestEnvironment(IDictionary variables) : this(variables, is64BitProcess: true) { } From d175f058a78c65b9f64e4d02b44203847feb1232 Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Wed, 20 Sep 2023 06:38:23 -0700 Subject: [PATCH 05/11] Adding E2E test. --- .../WebHostEndToEnd/SpecializationE2ETests.cs | 21 +++++++++++++++++++ .../TestEnvironment.cs | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/test/WebJobs.Script.Tests.Integration/WebHostEndToEnd/SpecializationE2ETests.cs b/test/WebJobs.Script.Tests.Integration/WebHostEndToEnd/SpecializationE2ETests.cs index ceb4160c8c..df845c97f0 100644 --- a/test/WebJobs.Script.Tests.Integration/WebHostEndToEnd/SpecializationE2ETests.cs +++ b/test/WebJobs.Script.Tests.Integration/WebHostEndToEnd/SpecializationE2ETests.cs @@ -830,6 +830,7 @@ public async Task DotNetIsolated_PlaceholderHit() var log = _loggerProvider.GetLog(); Assert.Contains("UsePlaceholderDotNetIsolated: True", log); + Assert.Contains("Is64BitProcess: True", log); Assert.Contains("Placeholder runtime version: '6.0'. Site runtime version: '6.0'. Match: True", log); Assert.DoesNotContain("Shutting down placeholder worker.", log); } @@ -880,6 +881,7 @@ public async Task DotNetIsolated_PlaceholderHit_WithProxies() var log = _loggerProvider.GetLog(); Assert.Contains("UsePlaceholderDotNetIsolated: True", log); + Assert.Contains("Is64BitProcess: True", log); Assert.Contains("Placeholder runtime version: '6.0'. Site runtime version: '6.0'. Match: True", log); Assert.DoesNotContain("Shutting down placeholder worker.", log); } @@ -895,6 +897,24 @@ public async Task DotNetIsolated_PlaceholderMiss_EnvVar() Assert.Contains("Shutting down placeholder worker. Worker is not compatible for runtime: dotnet-isolated", log); } + [Fact] + public async Task DotNetIsolated_PlaceholderMiss_Not64Bit() + { + _environment.SetProcessBitness(is64Bitness: false); + + // We only specialize when host process is 64 bit process. + await DotNetIsolatedPlaceholderMiss(() => + { + _environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteUsePlaceholderDotNetIsolated, "1"); + _environment.SetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeVersionSettingName, "6.0"); + }); + + var log = _loggerProvider.GetLog(); + Assert.Contains("UsePlaceholderDotNetIsolated: True", log); + Assert.Contains("Is64BitProcess: False", log); + Assert.Contains("Shutting down placeholder worker. Worker is not compatible for runtime: dotnet-isolated", log); + } + [Fact] public async Task DotNetIsolated_PlaceholderMiss_DotNetVer() { @@ -908,6 +928,7 @@ await DotNetIsolatedPlaceholderMiss(() => var log = _loggerProvider.GetLog(); Assert.Contains("UsePlaceholderDotNetIsolated: True", log); + Assert.Contains("Is64BitProcess: True", log); Assert.Contains("Placeholder runtime version: '6.0'. Site runtime version: '7.0'. Match: False", log); Assert.Contains("Shutting down placeholder worker. Worker is not compatible for runtime: dotnet-isolated", log); } diff --git a/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs b/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs index e819f5ec83..d8af0c5f26 100644 --- a/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs +++ b/test/WebJobs.Script.Tests.Shared/TestEnvironment.cs @@ -63,5 +63,10 @@ public static TestEnvironment FromEnvironmentVariables() return new TestEnvironment(variables); } + + public void SetProcessBitness(bool is64Bitness) + { + _is64BitProcess = is64Bitness; + } } } From aed02966633c2d80c8cc8f0b93114a162de8d0d7 Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Fri, 22 Sep 2023 11:30:31 -0700 Subject: [PATCH 06/11] Improving log message. --- .../Workers/Rpc/WebHostRpcWorkerChannelManager.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs b/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs index 745b14f464..ee3de38473 100644 --- a/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs +++ b/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs @@ -182,11 +182,9 @@ private bool UsePlaceholderChannel(IRpcWorkerChannel channel) } // We support specialization of dotnet-isolated only on 64bit host process. - var is64Bit = _environment.Is64BitProcess; - _logger.LogDebug("Is64BitProcess: {is64Bit}", is64Bit.ToString()); - - if (!is64Bit) + if (!_environment.Is64BitProcess) { + _logger.LogDebug("This app is configured as 32-bit and therefore does not leverage all performance optimizations. See https://aka.ms/azure-functions/dotnet/placeholders for more information."); return false; } From 00691039c04d5f4281d7bbc4577800aefda5ac43 Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Fri, 22 Sep 2023 11:34:46 -0700 Subject: [PATCH 07/11] Switch from LogDebug to LogInformation --- .../Workers/Rpc/WebHostRpcWorkerChannelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs b/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs index ee3de38473..64a49153e5 100644 --- a/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs +++ b/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs @@ -184,7 +184,7 @@ private bool UsePlaceholderChannel(IRpcWorkerChannel channel) // We support specialization of dotnet-isolated only on 64bit host process. if (!_environment.Is64BitProcess) { - _logger.LogDebug("This app is configured as 32-bit and therefore does not leverage all performance optimizations. See https://aka.ms/azure-functions/dotnet/placeholders for more information."); + _logger.LogInformation("This app is configured as 32-bit and therefore does not leverage all performance optimizations. See https://aka.ms/azure-functions/dotnet/placeholders for more information."); return false; } From fbbea73460b257e4435ce43368629609686189d8 Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Fri, 22 Sep 2023 11:39:51 -0700 Subject: [PATCH 08/11] Fix tests to reflect logging changes --- .../WebHostEndToEnd/SpecializationE2ETests.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/WebJobs.Script.Tests.Integration/WebHostEndToEnd/SpecializationE2ETests.cs b/test/WebJobs.Script.Tests.Integration/WebHostEndToEnd/SpecializationE2ETests.cs index df845c97f0..27e343fc73 100644 --- a/test/WebJobs.Script.Tests.Integration/WebHostEndToEnd/SpecializationE2ETests.cs +++ b/test/WebJobs.Script.Tests.Integration/WebHostEndToEnd/SpecializationE2ETests.cs @@ -830,7 +830,6 @@ public async Task DotNetIsolated_PlaceholderHit() var log = _loggerProvider.GetLog(); Assert.Contains("UsePlaceholderDotNetIsolated: True", log); - Assert.Contains("Is64BitProcess: True", log); Assert.Contains("Placeholder runtime version: '6.0'. Site runtime version: '6.0'. Match: True", log); Assert.DoesNotContain("Shutting down placeholder worker.", log); } @@ -881,7 +880,6 @@ public async Task DotNetIsolated_PlaceholderHit_WithProxies() var log = _loggerProvider.GetLog(); Assert.Contains("UsePlaceholderDotNetIsolated: True", log); - Assert.Contains("Is64BitProcess: True", log); Assert.Contains("Placeholder runtime version: '6.0'. Site runtime version: '6.0'. Match: True", log); Assert.DoesNotContain("Shutting down placeholder worker.", log); } @@ -911,7 +909,7 @@ await DotNetIsolatedPlaceholderMiss(() => var log = _loggerProvider.GetLog(); Assert.Contains("UsePlaceholderDotNetIsolated: True", log); - Assert.Contains("Is64BitProcess: False", log); + Assert.Contains("This app is configured as 32-bit and therefore does not leverage all performance optimizations. See https://aka.ms/azure-functions/dotnet/placeholders for more information.", log); Assert.Contains("Shutting down placeholder worker. Worker is not compatible for runtime: dotnet-isolated", log); } @@ -928,7 +926,6 @@ await DotNetIsolatedPlaceholderMiss(() => var log = _loggerProvider.GetLog(); Assert.Contains("UsePlaceholderDotNetIsolated: True", log); - Assert.Contains("Is64BitProcess: True", log); Assert.Contains("Placeholder runtime version: '6.0'. Site runtime version: '7.0'. Match: False", log); Assert.Contains("Shutting down placeholder worker. Worker is not compatible for runtime: dotnet-isolated", log); } From b34c5b92afcad14768f4dcb4c086b63e7267688c Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Wed, 27 Sep 2023 10:47:27 -0700 Subject: [PATCH 09/11] Logging with EventId --- .../Workers/Rpc/WebHostRpcWorkerChannelManager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs b/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs index 64a49153e5..55a75b803f 100644 --- a/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs +++ b/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs @@ -184,7 +184,8 @@ private bool UsePlaceholderChannel(IRpcWorkerChannel channel) // We support specialization of dotnet-isolated only on 64bit host process. if (!_environment.Is64BitProcess) { - _logger.LogInformation("This app is configured as 32-bit and therefore does not leverage all performance optimizations. See https://aka.ms/azure-functions/dotnet/placeholders for more information."); + _logger.LogInformation(new EventId(421, "PlaceholderMissDueToBitness"), + "This app is configured as 32-bit and therefore does not leverage all performance optimizations. See https://aka.ms/azure-functions/dotnet/placeholders for more information."); return false; } From c52f68fe5ae43aaa11af2633ecf106a70893e9a2 Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Wed, 27 Sep 2023 14:27:21 -0700 Subject: [PATCH 10/11] Logging using an event name --- src/WebJobs.Script/ScriptConstants.cs | 1 + .../Workers/Rpc/WebHostRpcWorkerChannelManager.cs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/WebJobs.Script/ScriptConstants.cs b/src/WebJobs.Script/ScriptConstants.cs index fac9d335d6..d5cd475d31 100644 --- a/src/WebJobs.Script/ScriptConstants.cs +++ b/src/WebJobs.Script/ScriptConstants.cs @@ -88,6 +88,7 @@ public static class ScriptConstants public const string DefaultMasterKeyName = "master"; public const string DefaultFunctionKeyName = "default"; public const string ColdStartEventName = "ColdStart"; + public const string PlaceholderMissDueToBitnessEventName = "PlaceholderMissDueToBitness"; public const string FunctionsUserAgent = "AzureFunctionsRuntime"; public const string HttpScaleUserAgent = "HttpScaleManager"; diff --git a/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs b/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs index 55a75b803f..c02c23354a 100644 --- a/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs +++ b/src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs @@ -184,8 +184,9 @@ private bool UsePlaceholderChannel(IRpcWorkerChannel channel) // We support specialization of dotnet-isolated only on 64bit host process. if (!_environment.Is64BitProcess) { - _logger.LogInformation(new EventId(421, "PlaceholderMissDueToBitness"), + _logger.LogInformation(new EventId(421, ScriptConstants.PlaceholderMissDueToBitnessEventName), "This app is configured as 32-bit and therefore does not leverage all performance optimizations. See https://aka.ms/azure-functions/dotnet/placeholders for more information."); + return false; } From 7bb3a5bb947b5588f59f567beffafe62ce8a0250 Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Wed, 27 Sep 2023 14:32:31 -0700 Subject: [PATCH 11/11] Updated release notes after rebase merge --- release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/release_notes.md b/release_notes.md index 52c3aed307..6139d02073 100644 --- a/release_notes.md +++ b/release_notes.md @@ -16,3 +16,4 @@ - This fixes a bug with worker indexing where we are shutting down worker channels and creating a new channel that never gets properly initialized as the invocation buffers are not created - this leads to a "Did not find initialized workers" error. - Check if a blob container or table exists before trying to create it (#9555) +- Limit dotnet-isolated specialization to 64 bit host process (#9548) \ No newline at end of file