Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
e18fe94
Changes to add DynamicWorkerConfigResolver
surgupta-msft Aug 15, 2025
60d4414
Adding tests
surgupta-msft Aug 15, 2025
5b2d5ff
Code cleanup
surgupta-msft Aug 17, 2025
37ad909
Cleanup code
surgupta-msft Aug 17, 2025
b4ca3db
Cleanup RpcWorkerConfigFactoryTests
surgupta-msft Aug 17, 2025
5bc50ee
Tests cleanup
surgupta-msft Aug 17, 2025
e2349e9
Tests update
surgupta-msft Aug 17, 2025
c86e2e7
build fix
surgupta-msft Aug 17, 2025
1e9301d
Added logic to ignore worker versions specified via config
surgupta-msft Aug 18, 2025
56d7918
Added test in SpecializationE2ETest
surgupta-msft Aug 18, 2025
21cfe06
Updated DynamicWorkerConfigResolver
surgupta-msft Aug 18, 2025
d6883ab
Updated utility
surgupta-msft Aug 18, 2025
3417d99
Fixed test. Added comments in resolver and options setup class
surgupta-msft Aug 19, 2025
c8ec8bf
Fixed FunctionsHostingConfigOptionsTest
surgupta-msft Aug 19, 2025
4b344e4
Code improvement, added logs
surgupta-msft Aug 20, 2025
61db33b
Addressing PR feedback
surgupta-msft Aug 20, 2025
12c95da
Adding token extensions methods
surgupta-msft Aug 21, 2025
15bbd31
Refactored token extensions class
surgupta-msft Aug 21, 2025
47d86f1
Updating TokenExtensions
surgupta-msft Aug 21, 2025
7ce1414
Reverting tokenExtensions changes
surgupta-msft Aug 21, 2025
17c4209
Merge branch 'dev' into surgupta/dynamic-worker-resolver
surgupta-msft Aug 23, 2025
1cbc0a7
Addressing PR feedback
surgupta-msft Aug 24, 2025
74d77b2
Added tests
surgupta-msft Aug 24, 2025
6f3cb9e
Addressing PR feedback, code cleanup
surgupta-msft Aug 24, 2025
d389a5e
Added tests for RPCWorkerConfigFactory
surgupta-msft Aug 25, 2025
a467a6e
Cleanup WorkerConfigurationResolverOptionsSetup
surgupta-msft Aug 25, 2025
5186c44
Minor renaming, added tests
surgupta-msft Aug 25, 2025
0e2056a
Minor code improvement, comments update in DynamicWorkerConfiguration…
surgupta-msft Aug 25, 2025
3b5428c
Added tests in DynamicWorkerConfigurationResolverTests
surgupta-msft Aug 25, 2025
e91d86a
Logging and tests update
surgupta-msft Aug 26, 2025
adb8980
Merge branch 'dev' into surgupta/dynamic-worker-resolver
surgupta-msft Aug 26, 2025
8887ee1
Added release notes
surgupta-msft Aug 26, 2025
27d80d6
Addressing PR feedback, variable renaming
surgupta-msft Aug 28, 2025
236ec49
Merge branch 'dev' into surgupta/dynamic-worker-resolver
surgupta-msft Aug 28, 2025
8e91769
Updating reelase notes
surgupta-msft Aug 28, 2025
3b1cfde
Added log and summary comment
surgupta-msft Aug 28, 2025
b964261
Addressing PR feedback
surgupta-msft Aug 29, 2025
2afb262
Merge branch 'dev' into surgupta/dynamic-worker-resolver
surgupta-msft Aug 29, 2025
a680663
Resolving release notes conflict
surgupta-msft Aug 29, 2025
5f84d9c
Modifying code to use config Get method
surgupta-msft Aug 31, 2025
d38d1c3
Using immutable objects
surgupta-msft Sep 1, 2025
7002a14
Reverted RPCWorkerDescription change
surgupta-msft Sep 2, 2025
669473e
Using deserialization to get HostRequirements
surgupta-msft Sep 2, 2025
16b42fa
Merge branch 'dev' into surgupta/dynamic-worker-resolver
surgupta-msft Sep 2, 2025
b0b9e49
resolving release notes conflict
surgupta-msft Sep 2, 2025
80515a3
Addressing PR comments
surgupta-msft Sep 2, 2025
2109535
Fix release notes incorrect merge
surgupta-msft Sep 3, 2025
b3cce91
Using Config Get method to parse RPCWorkerDescription
surgupta-msft Sep 4, 2025
a311bf6
Merge branch 'dev' into surgupta/dynamic-worker-resolver
surgupta-msft Sep 4, 2025
f9504a9
Fix release notes conflict
surgupta-msft Sep 4, 2025
dfb1272
Fixing nits
surgupta-msft Sep 4, 2025
2c2a864
Refactoring code for profile evaluation (#11301)
surgupta-msft Sep 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
### Release notes

<!-- Please add your release notes in the following format:
- My change description (#PR)
-->
- Rev `Microsoft.Azure.Functions.DotNetIsolatedNativeHost` to `1.0.13` (#11269)
- Refactor telemetry & exporter setup: deprecations, noise reduction, and API updates (#11260)
- Update Python Worker Version to [4.39.2](https://github.com/Azure/azure-functions-python-worker/releases/tag/4.39.2)
- Add JitTrace Files for v4.1043 (#11281)
### Release notes

<!-- Please add your release notes in the following format:
- My change description (#PR)
-->
- Rev `Microsoft.Azure.Functions.DotNetIsolatedNativeHost` to `1.0.13` (#11269)
- Refactor telemetry & exporter setup: deprecations, noise reduction, and API updates (#11260)
- Update Python Worker Version to [4.39.2](https://github.com/Azure/azure-functions-python-worker/releases/tag/4.39.2)
- Add JitTrace Files for v4.1043 (#11281)
- Implementing a resolver that resolves worker configurations from specified probing paths (#11258)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
Expand Down Expand Up @@ -234,7 +234,18 @@ public static void AddWebJobsScriptHost(this IServiceCollection services, IConfi
services.ConfigureOptionsWithChangeTokenSource<WorkerConfigurationResolverOptions, WorkerConfigurationResolverOptionsSetup, HostBuiltChangeTokenSource<WorkerConfigurationResolverOptions>>();
services.ConfigureOptionsWithChangeTokenSource<LanguageWorkerOptions, LanguageWorkerOptionsSetup, HostBuiltChangeTokenSource<LanguageWorkerOptions>>();

services.AddSingleton<IWorkerConfigurationResolver, DefaultWorkerConfigurationResolver>();
services.AddSingleton<IWorkerConfigurationResolver>(p =>
{
var workerConfigurationResolverOptions = p.GetService<IOptionsMonitor<WorkerConfigurationResolverOptions>>();
var workerProfileManager = p.GetService<IWorkerProfileManager>();
var loggerFactory = p.GetService<ILoggerFactory>();
var metricsLogger = p.GetService<IMetricsLogger>();

return workerConfigurationResolverOptions?.CurrentValue?.IsDynamicWorkerResolutionEnabled is true ?
new DynamicWorkerConfigurationResolver(loggerFactory, metricsLogger, FileUtility.Instance, workerProfileManager, SystemRuntimeInformation.Instance, workerConfigurationResolverOptions) :
new DefaultWorkerConfigurationResolver(loggerFactory, metricsLogger, FileUtility.Instance, workerProfileManager, SystemRuntimeInformation.Instance, workerConfigurationResolverOptions);
});

services.TryAddSingleton<IDependencyValidator, DependencyValidator>();
services.TryAddSingleton<IJobHostMiddlewarePipeline>(s => DefaultMiddlewarePipeline.Empty);

Expand Down
25 changes: 24 additions & 1 deletion src/WebJobs.Script/Config/FunctionsHostingConfigOptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
Expand Down Expand Up @@ -91,6 +91,29 @@ internal string WorkerIndexingDisabledApps
}
}

/// <summary>
/// Gets a string delimited by '|' that contains the names of the language workers available through probing paths outside of the Host.
/// </summary>
internal string WorkersAvailableForDynamicResolution
{
get
{
return GetFeature(RpcWorkerConstants.WorkersAvailableForDynamicResolution) ?? string.Empty;
}
}

/// <summary>
/// Gets a string delimited by '|' that contains the versions of language workers to be ignored during probing outside of the Host.
/// Example value: "Worker1Name:Version1|Worker1Name:Version2|Worker2Name:Version1|Worker3Name:Version1".
/// </summary>
internal string IgnoredWorkerVersions
{
get
{
return GetFeature(RpcWorkerConstants.IgnoredWorkerVersions) ?? string.Empty;
}
}

/// <summary>
/// Gets a value indicating whether Linux Log Backoff is disabled in the hosting config.
/// </summary>
Expand Down
10 changes: 10 additions & 0 deletions src/WebJobs.Script/Diagnostics/Extensions/LoggerExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ internal static class LoggerExtension
new EventId(343, nameof(DefaultWorkersDirectoryPath)),
"Workers Directory set to: {workersDirPath}");

private static readonly Action<ILogger, string, Exception> _workerProbingPaths =
LoggerMessage.Define<string>(LogLevel.Debug,
new EventId(344, nameof(WorkerProbingPaths)),
"Worker probing paths set to: {workerProbingPaths}");

public static void PublishingMetrics(this ILogger logger, string metrics)
{
_publishingMetrics(logger, metrics, null);
Expand Down Expand Up @@ -423,6 +428,11 @@ public static void DefaultWorkersDirectoryPath(this ILogger logger, string worke
_defaultWorkersDirectoryPath(logger, workersDirPath, null);
}

public static void WorkerProbingPaths(this ILogger logger, string workerProbingPaths)
{
_workerProbingPaths(logger, workerProbingPaths, null);
}

public static void OutdatedExtensionBundle(this ILogger logger, string currentVersion)
{
_outdatedExtensionBundle(logger, currentVersion, null);
Expand Down
22 changes: 21 additions & 1 deletion src/WebJobs.Script/Environment/EnvironmentExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
Expand Down Expand Up @@ -278,6 +278,16 @@ public static bool IsWindowsElasticPremium(this IEnvironment environment)
return string.Equals(value, ScriptConstants.ElasticPremiumSku, StringComparison.OrdinalIgnoreCase);
}

/// <summary>
/// Gets a value indicating whether the application is running in a Windows App Service environment.
/// </summary>
/// <param name="environment">The environment to verify.</param>
/// <returns><see cref="true"/> if running in a Windows App Service app; otherwise, false.</returns>
public static bool IsHostedWindowsEnvironment(this IEnvironment environment)
{
return environment.IsWindowsAzureManagedHosting() || environment.IsWindowsConsumption() || environment.IsWindowsElasticPremium();
}

public static bool IsDynamicSku(this IEnvironment environment)
{
return environment.IsConsumptionSku() || environment.IsWindowsElasticPremium();
Expand Down Expand Up @@ -687,6 +697,16 @@ public static bool IsInProc(this IEnvironment environment, string workerRuntime
return string.IsNullOrEmpty(workerRuntime) || string.Equals(workerRuntime, RpcWorkerConstants.DotNetLanguageWorkerName, StringComparison.OrdinalIgnoreCase);
}

/// <summary>
/// Returns the Antares platform release channel specified by the environment variable.
/// Value of this variable could be "LATEST", "STANDARD" or "EXTENDED".
/// If the environment variable is not set, the method returns the default value "LATEST".
/// </summary>
public static string GetPlatformReleaseChannel(this IEnvironment environment)
{
return environment.GetEnvironmentVariable(AntaresPlatformReleaseChannel) ?? ScriptConstants.LatestPlatformChannelNameUpper;
}

public static bool IsApplicationInsightsAgentEnabled(this IEnvironment environment)
{
// cache the value of the environment variable
Expand Down
3 changes: 2 additions & 1 deletion src/WebJobs.Script/Environment/EnvironmentSettingNames.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

namespace Microsoft.Azure.WebJobs.Script
Expand Down Expand Up @@ -35,6 +35,7 @@ public static class EnvironmentSettingNames
public const string AppInsightsAgent = "APPLICATIONINSIGHTS_ENABLE_AGENT";
public const string FunctionsExtensionVersion = "FUNCTIONS_EXTENSION_VERSION";
public const string FunctionWorkerRuntime = "FUNCTIONS_WORKER_RUNTIME";
public const string WorkerProbingPaths = "WORKER_PROBING_PATHS";
public const string ContainerName = "CONTAINER_NAME";
public const string WebsitePodName = "WEBSITE_POD_NAME";
public const string LegionServiceHost = "LEGION_SERVICE_HOST";
Expand Down
16 changes: 16 additions & 0 deletions src/WebJobs.Script/JsonSerializerOptionsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ public static class JsonSerializerOptionsProvider
/// </summary>
public static readonly JsonSerializerOptions Options = CreateJsonOptions();

/// <summary>
/// Shared Json serializer with the following settings:
/// - PropertyNameCaseInsensitive: true.
/// </summary>
public static readonly JsonSerializerOptions WorkerConfigJsonSerializerOptions = CreateWorkerConfigJsonOptions();

private static JsonSerializerOptions CreateJsonOptions()
{
var options = new JsonSerializerOptions
Expand All @@ -32,5 +38,15 @@ private static JsonSerializerOptions CreateJsonOptions()

return options;
}

private static JsonSerializerOptions CreateWorkerConfigJsonOptions()
{
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};

return options;
}
}
}
4 changes: 3 additions & 1 deletion src/WebJobs.Script/ScriptConstants.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
Expand Down Expand Up @@ -133,6 +133,7 @@ public static class ScriptConstants
public const string FeatureFlagDisableWebHostLogForwarding = "DisableWebHostLogForwarding";
public const string FeatureFlagDisableMergedWebHostScriptHostConfiguration = "DisableMergedConfiguration";
public const string FeatureFlagEnableWorkerIndexing = "EnableWorkerIndexing";
public const string FeatureFlagDisableDynamicWorkerResolution = "DisableDynamicWorkerResolution";
public const string FeatureFlagEnableDebugTracing = "EnableDebugTracing";
public const string FeatureFlagEnableProxies = "EnableProxies";
public const string FeatureFlagStrictHISModeEnabled = "StrictHISModeEnabled";
Expand Down Expand Up @@ -248,6 +249,7 @@ public static class ScriptConstants
public static readonly long DefaultMaxRequestBodySize = 104857600;

public static readonly ImmutableArray<string> SystemLogCategoryPrefixes = ImmutableArray.Create("Microsoft.Azure.WebJobs.", "Function.", "Worker.", "Host.");
public static readonly ImmutableHashSet<string> HostCapabilities = ImmutableHashSet.Create<string>(StringComparer.OrdinalIgnoreCase);

public static readonly string FunctionMetadataDirectTypeKey = "DirectType";
public static readonly string LiveLogsSessionAIKey = "#AzFuncLiveLogsSessionId";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Abstractions;
using Microsoft.Azure.WebJobs.Script.Diagnostics;
using Microsoft.Azure.WebJobs.Script.Diagnostics.Extensions;
using Microsoft.Azure.WebJobs.Script.Workers.Profiles;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

Expand All @@ -15,36 +18,75 @@ internal sealed class DefaultWorkerConfigurationResolver : IWorkerConfigurationR
{
private readonly ILogger _logger;
private readonly IOptionsMonitor<WorkerConfigurationResolverOptions> _workerConfigurationResolverOptions;
private readonly IMetricsLogger _metricsLogger;
private readonly IWorkerProfileManager _profileManager;
private readonly IFileSystem _fileSystem;
private readonly ISystemRuntimeInformation _systemRuntimeInformation;

public DefaultWorkerConfigurationResolver(ILoggerFactory loggerFactory,
IMetricsLogger metricsLogger,
IFileSystem fileSystem,
IWorkerProfileManager workerProfileManager,
ISystemRuntimeInformation systemRuntimeInformation,
IOptionsMonitor<WorkerConfigurationResolverOptions> workerConfigurationResolverOptions)
{
ArgumentNullException.ThrowIfNull(loggerFactory);
_logger = loggerFactory.CreateLogger(ScriptConstants.LogCategoryWorkerConfig);
_workerConfigurationResolverOptions = workerConfigurationResolverOptions ?? throw new ArgumentNullException(nameof(workerConfigurationResolverOptions));
_metricsLogger = metricsLogger ?? throw new ArgumentNullException(nameof(metricsLogger));
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
_profileManager = workerProfileManager ?? throw new ArgumentNullException(nameof(workerProfileManager));
_systemRuntimeInformation = systemRuntimeInformation ?? throw new ArgumentNullException(nameof(systemRuntimeInformation));
}

public WorkerConfigurationInfo GetConfigurationInfo()
public Dictionary<string, RpcWorkerConfig> GetWorkerConfigs()
{
var workersRootDirPath = _workerConfigurationResolverOptions.CurrentValue.WorkersRootDirPath;
_logger.DefaultWorkersDirectoryPath(workersRootDirPath);
_logger.DefaultWorkersDirectoryPath(_workerConfigurationResolverOptions.CurrentValue.WorkersRootDirPath);

var workerConfigPaths = new List<string>();
return ResolveWorkerConfigsFromWithinHost(_workerConfigurationResolverOptions.CurrentValue,
_logger,
_fileSystem,
_metricsLogger,
_systemRuntimeInformation,
_profileManager);
}

internal static Dictionary<string, RpcWorkerConfig> ResolveWorkerConfigsFromWithinHost(WorkerConfigurationResolverOptions resolverOptions,
ILogger logger,
IFileSystem fileSystem,
IMetricsLogger metricsLogger,
ISystemRuntimeInformation systemRuntimeInformation,
IWorkerProfileManager profileManager,
Dictionary<string, RpcWorkerConfig> runtimeToConfigMap = null)
{
runtimeToConfigMap = runtimeToConfigMap ?? [];

foreach (var workerDir in _fileSystem.Directory.EnumerateDirectories(workersRootDirPath))
foreach (var workerPath in fileSystem.Directory.EnumerateDirectories(resolverOptions.WorkersRootDirPath))
{
string workerConfigPath = _fileSystem.Path.Combine(workerDir, RpcWorkerConstants.WorkerConfigFileName);
string workerDir = Path.GetFileName(workerPath);

if (runtimeToConfigMap.ContainsKey(workerDir))
{
continue;
}

string workerConfigPath = Path.Combine(workerPath, RpcWorkerConstants.WorkerConfigFileName);
if (File.Exists(workerConfigPath))
{
var workerConfig = WorkerConfigurationHelper.AddProvider(resolverOptions, workerPath, metricsLogger, logger, systemRuntimeInformation, profileManager);
if (workerConfig is not null)
{
runtimeToConfigMap[workerDir] = workerConfig;
}
}

if (_fileSystem.File.Exists(workerConfigPath))
if (WorkerConfigurationHelper.FoundWorkerConfig(resolverOptions.WorkerRuntime, runtimeToConfigMap, resolverOptions.IsPlaceholderModeEnabled, resolverOptions.IsMultiLanguageWorkerEnvironment))
{
workerConfigPaths.Add(workerDir);
break;
}
}

return new WorkerConfigurationInfo(_workerConfigurationResolverOptions.CurrentValue.WorkersRootDirPath, workerConfigPaths);
return runtimeToConfigMap;
}
}
}
Loading
Loading