Skip to content

Commit 49325e6

Browse files
authored
Initial block for .NET in-proc indexing in the OOP host. (#10573)
1 parent 93dd5eb commit 49325e6

File tree

8 files changed

+56
-10
lines changed

8 files changed

+56
-10
lines changed

release_notes.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616
- Update PowerShell 7.4 worker to [4.0.4026](https://github.com/Azure/azure-functions-powershell-worker/releases/tag/v4.0.4026)
1717
- Added support for identity-based connections to Diagnostic Events (#10438)
1818
- Updating Microsoft.Azure.WebJobs.Logging.ApplicationInsights to 3.0.42-12121
19-
- Updated retry logic in Worker HTTP proxy to allow for longer worker HTTP listener initialization times (#10566).
19+
- Updated retry logic in Worker HTTP proxy to allow for longer worker HTTP listener initialization times (#10566).
20+
- Introduced proper handling in environments where .NET in-proc is not supported.

src/WebJobs.Script/Config/FunctionsHostingConfigOptions.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections.Generic;
66
using System.Linq;
77
using Microsoft.AspNetCore.Http;
8+
using Microsoft.Azure.WebJobs.Script.Workers.Http;
89
using Microsoft.Azure.WebJobs.Script.Workers.Rpc;
910

1011
namespace Microsoft.Azure.WebJobs.Script.Config
@@ -212,6 +213,14 @@ internal bool WorkerRuntimeStrictValidationEnabled
212213
}
213214
}
214215

216+
internal bool IsDotNetInProcDisabled
217+
{
218+
get
219+
{
220+
return GetFeatureAsBooleanOrDefault(ScriptConstants.HostingConfigDotNetInProcDisabled, false);
221+
}
222+
}
223+
215224
/// <summary>
216225
/// Gets feature by name.
217226
/// </summary>

src/WebJobs.Script/Environment/EnvironmentExtensions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ public static bool AzureFilesAppSettingsExist(this IEnvironment environment)
115115
!string.IsNullOrEmpty(environment.GetEnvironmentVariable(AzureFilesContentShare));
116116
}
117117

118+
public static bool IsDotNetInProcSupported(this IEnvironment environment)
119+
{
120+
return !IsFlexConsumptionSku(environment)
121+
&& !string.Equals(environment.GetEnvironmentVariable(EnvironmentSettingNames.FunctionsDisableInProc), "1", StringComparison.OrdinalIgnoreCase);
122+
}
123+
118124
public static string GetAzureWebsiteHomePath(this IEnvironment environment)
119125
{
120126
return environment.GetEnvironmentVariable(AzureWebsiteHomePath);

src/WebJobs.Script/Environment/EnvironmentSettingNames.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public static class EnvironmentSettingNames
8383
public const string FunctionsWebsiteTimeZone = "WEBSITE_TIME_ZONE";
8484
public const string FunctionsTargetGroup = "FUNCTIONS_TARGET_GROUP";
8585
public const string WebsiteArmResourceId = "WEBSITE_ARM_RESOURCE_ID";
86+
public const string FunctionsDisableInProc = "FUNCTIONS_DISABLE_INPROC";
8687

8788
//Function in Kubernetes
8889
public const string PodNamespace = "POD_NAMESPACE";

src/WebJobs.Script/Extensions/FunctionMetadataExtensions.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@ public static bool IsDirect(this FunctionMetadata metadata)
124124
return result;
125125
}
126126

127+
public static bool IsDotNetInProc(this FunctionMetadata metadata)
128+
{
129+
return metadata.IsDirect()
130+
|| (string.Equals(metadata.Language, DotNetScriptTypes.CSharp, StringComparison.OrdinalIgnoreCase)
131+
|| string.Equals(metadata.Language, DotNetScriptTypes.DotNetAssembly, StringComparison.OrdinalIgnoreCase)
132+
|| string.Equals(metadata.Language, DotNetScriptTypes.RawDotNetAssembly, StringComparison.OrdinalIgnoreCase));
133+
}
134+
127135
public static bool IsDisabled(this FunctionMetadata metadata)
128136
{
129137
Utility.TryReadAsBool(metadata.Properties, IsDisabledKey, out bool result);

src/WebJobs.Script/Host/ScriptHost.cs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ private void VerifyPrecompileStatus(IEnumerable<FunctionDescriptor> functions)
737737
scriptFile);
738738

739739
// Adding a function error will cause this function to get ignored
740-
Utility.AddFunctionError(this.FunctionErrors, metadata.Name, msg);
740+
Utility.AddFunctionError(FunctionErrors, metadata.Name, msg);
741741

742742
_logger.ConfigurationError(msg);
743743
}
@@ -823,15 +823,34 @@ internal async Task<Collection<FunctionDescriptor>> GetFunctionDescriptorsAsync(
823823

824824
Utility.VerifyFunctionsMatchSpecifiedLanguage(functions, workerRuntime, _environment.IsPlaceholderModeEnabled(), _isHttpWorker, cancellationToken, throwOnMismatch: throwOnWorkerRuntimeAndPayloadMetadataMismatch);
825825

826+
var inProcIndexingSupported = _environment.IsPlaceholderModeEnabled()
827+
|| (_environment.IsDotNetInProcSupported()
828+
&& !_hostingConfigOptions.Value.IsDotNetInProcDisabled);
829+
826830
foreach (FunctionMetadata metadata in functions)
827831
{
828832
try
829833
{
830-
bool created = false;
834+
// If this is metadata represents a function that requires direct type indexing (in-proc), and that is not supported,
835+
// throw an exception with detailed information.
836+
// This is temporary and will be removed in a future release, along with all other logic to support the in-proc model.
837+
if (metadata.IsDotNetInProc())
838+
{
839+
if (!inProcIndexingSupported)
840+
{
841+
throw new HostInitializationException(".NET In-process function detected. This model is not supported by the host in the current environment." +
842+
" See https://aka.ms/azure-functions-retirements/in-process-model for more information.");
843+
}
844+
845+
// If this is metadata represents a function that supports direct type indexing,
846+
// set that type in the function metadata
847+
TrySetDirectType(metadata);
848+
}
849+
831850
FunctionDescriptor descriptor = null;
832851
foreach (var provider in descriptorProviders)
833852
{
834-
(created, descriptor) = await provider.TryCreate(metadata);
853+
(bool created, descriptor) = await provider.TryCreate(metadata);
835854
if (created)
836855
{
837856
break;
@@ -843,12 +862,8 @@ internal async Task<Collection<FunctionDescriptor>> GetFunctionDescriptorsAsync(
843862
ValidateFunction(descriptor, httpFunctions, _environment);
844863
functionDescriptors.Add(descriptor);
845864
}
846-
847-
// If this is metadata represents a function that supports direct type indexing,
848-
// set that type int he function metadata
849-
TrySetDirectType(metadata);
850865
}
851-
catch (Exception ex)
866+
catch (Exception ex) when (ex is not HostInitializationException)
852867
{
853868
// log any unhandled exceptions and continue
854869
Utility.AddFunctionError(FunctionErrors, metadata.Name, Utility.FlattenException(ex, includeSource: false));

src/WebJobs.Script/ScriptConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ public static class ScriptConstants
144144
public const string HostingConfigSwtAuthenticationEnabled = "SwtAuthenticationEnabled";
145145
public const string HostingConfigSwtIssuerEnabled = "SwtIssuerEnabled";
146146
public const string HostingConfigInternalAuthApisAllowList = "InternalAuthApisAllowList";
147+
public const string HostingConfigDotNetInProcDisabled = "DotNetInProcDisabled";
147148

148149
public const string SiteAzureFunctionsUriFormat = "https://{0}.azurewebsites.net/azurefunctions";
149150
public const string ScmSiteUriFormat = "https://{0}.scm.azurewebsites.net";

test/WebJobs.Script.Tests/Configuration/FunctionsHostingConfigOptionsTest.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,12 @@ public void Property_Validation()
142142
(nameof(FunctionsHostingConfigOptions.WorkerRuntimeStrictValidationEnabled), "WORKER_RUNTIME_STRICT_VALIDATION_ENABLED=1", true),
143143

144144
(nameof(FunctionsHostingConfigOptions.InternalAuthApisAllowList), "InternalAuthApisAllowList=|", "|"),
145-
(nameof(FunctionsHostingConfigOptions.InternalAuthApisAllowList), "InternalAuthApisAllowList=/admin/host/foo|/admin/host/bar", "/admin/host/foo|/admin/host/bar")
145+
(nameof(FunctionsHostingConfigOptions.InternalAuthApisAllowList), "InternalAuthApisAllowList=/admin/host/foo|/admin/host/bar", "/admin/host/foo|/admin/host/bar"),
146+
147+
(nameof(FunctionsHostingConfigOptions.IsDotNetInProcDisabled), "DotNetInProcDisabled=False", false),
148+
(nameof(FunctionsHostingConfigOptions.IsDotNetInProcDisabled), "DotNetInProcDisabled=True", true),
149+
(nameof(FunctionsHostingConfigOptions.IsDotNetInProcDisabled), "DotNetInProcDisabled=1", true),
150+
(nameof(FunctionsHostingConfigOptions.IsDotNetInProcDisabled), "DotNetInProcDisabled=0", false),
146151
};
147152

148153
// use reflection to ensure that we have a test that uses every value exposed on FunctionsHostingConfigOptions

0 commit comments

Comments
 (0)