Remove Worker.Core assembly from DOTNET_STARTUP_HOOKS at startup (#1539)
This commit is contained in:
Родитель
35e29699bd
Коммит
a92c9278b8
|
@ -10,7 +10,7 @@
|
|||
|
||||
### Microsoft.Azure.Functions.Worker.Core <version>
|
||||
|
||||
- <event>
|
||||
- Fixed issue spawning child process while debugging due to "DOTNET_STARTUP_HOOKS" always containing "Microsoft.Azure.Functions.Worker.Core". (#1539)
|
||||
|
||||
### Microsoft.Azure.Functions.Worker.Grpc <version>
|
||||
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
/// <summary>
|
||||
|
@ -16,12 +19,17 @@ using System.Threading;
|
|||
/// </summary>
|
||||
internal class StartupHook
|
||||
{
|
||||
const string StartupHooksEnvVar = "DOTNET_STARTUP_HOOKS";
|
||||
private static readonly string _startupSeparator = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ";" : ":";
|
||||
private static readonly string? _assemblyName = typeof(StartupHook).Assembly.GetName().Name;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
// Time to wait between checks, in ms.
|
||||
const int SleepTime = 500;
|
||||
const int MaxWaitCycles = (60 * 1000) / SleepTime;
|
||||
|
||||
RemoveSelfFromStartupHooks();
|
||||
string? debuggerWaitEnabled = Environment.GetEnvironmentVariable("FUNCTIONS_ENABLE_DEBUGGER_WAIT");
|
||||
string? jsonOutputEnabled = Environment.GetEnvironmentVariable("FUNCTIONS_ENABLE_JSON_OUTPUT");
|
||||
#if NET5_0_OR_GREATER
|
||||
|
@ -62,4 +70,21 @@ internal class StartupHook
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void RemoveSelfFromStartupHooks()
|
||||
{
|
||||
string? startupHooks = Environment.GetEnvironmentVariable(StartupHooksEnvVar);
|
||||
if (string.IsNullOrEmpty(startupHooks))
|
||||
{
|
||||
// If this call happened, we are clearly part of this environment variable.
|
||||
// This is mostly to make strict-nulls happy.
|
||||
return;
|
||||
}
|
||||
|
||||
// netstandard2.0 has no StringSplitOptions overload.
|
||||
IEnumerable<string> parts = startupHooks.Split(_startupSeparator[0])
|
||||
.Where(x => !string.Equals(x, _assemblyName, StringComparison.Ordinal));
|
||||
string newValue = string.Join(_startupSeparator, parts);
|
||||
Environment.SetEnvironmentVariable(StartupHooksEnvVar, newValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Azure.Functions.Worker.Tests
|
||||
|
@ -10,7 +13,7 @@ namespace Microsoft.Azure.Functions.Worker.Tests
|
|||
public class StartupHookTests
|
||||
{
|
||||
[Fact]
|
||||
public void ValidadeHookSetup()
|
||||
public void ValidateHookSetup()
|
||||
{
|
||||
var hookType = typeof(StartupHook);
|
||||
var initializeMethod = hookType.GetMethod("Initialize", BindingFlags.Static | BindingFlags.Public);
|
||||
|
@ -24,5 +27,37 @@ namespace Microsoft.Azure.Functions.Worker.Tests
|
|||
Assert.Empty(initializeMethod.GetParameters());
|
||||
Assert.Equal(typeof(void), initializeMethod.ReturnType);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("Microsoft.Azure.Functions.Worker.Core")]
|
||||
[InlineData("Some.Other.Assembly")]
|
||||
[InlineData("Microsoft.Azure.Functions.Worker.Core", "Some.Other.Assembly")]
|
||||
[InlineData("Some.Other.Assembly", "Microsoft.Azure.Functions.Worker.Core")]
|
||||
[InlineData("Some.Other.Assembly", "Microsoft.Azure.Functions.Worker.Core", "Another.Assembly")]
|
||||
public void ValidateHookSetup_HookVariableRemoved(params string[] hooks)
|
||||
{
|
||||
hooks ??= Array.Empty<string>();
|
||||
char separator = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ';' : ':';
|
||||
string envVar = "DOTNET_STARTUP_HOOKS";
|
||||
string original = Environment.GetEnvironmentVariable(envVar);
|
||||
|
||||
try
|
||||
{
|
||||
IEnumerable<string> expected = hooks.Where(
|
||||
x => x != typeof(StartupHook).Assembly.GetName().Name);
|
||||
Environment.SetEnvironmentVariable(envVar, string.Join(separator, hooks));
|
||||
StartupHook.RemoveSelfFromStartupHooks();
|
||||
|
||||
string value = Environment.GetEnvironmentVariable(envVar);
|
||||
IEnumerable<string> actual = string.IsNullOrEmpty(value)
|
||||
? Enumerable.Empty<string>() : value.Split(separator);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Environment.SetEnvironmentVariable(envVar, original);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче