Skip to content

Commit 85b2144

Browse files
VpOfEngineeringsoninarenyojagadbrettsamgavin-aguiar
authored
4.21.1 hotfix (#9268)
* Switching the worker indexing to use hosting config feature flag (#9245) * Initial commit. * fixing issue with worker indexing, dotnet-isolated, and placeholders (#9253) * fixing issue with worker indexing, dotnet-isolated, and placeholders (#9253) * Update Python Worker Version to 4.14.0 (#9261) * Update Python Worker Version to 4.14.0 * Update release_notes.md --------- Co-authored-by: AzureFunctionsPython <[email protected]> * Setting up workerConfig with ConfigureOptionsWithChangeTokenSource (#9264) * Sending metadata request once per scriptHost instance (#9248) Co-authored-by: Brett Samblanet <[email protected]> * Restart workers when we need to refresh the worker metadata (#9244) * Incrementing patch version to 4.21.1 * Removing duplicate mention of #9253 --------- Co-authored-by: Naren Soni <[email protected]> Co-authored-by: Yogesh <[email protected]> Co-authored-by: Brett Samblanet <[email protected]> Co-authored-by: gavin-aguiar <[email protected]> Co-authored-by: AzureFunctionsPython <[email protected]> Co-authored-by: azfuncgh <[email protected]>
1 parent 996cf10 commit 85b2144

File tree

53 files changed

+890
-169
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+890
-169
lines changed

NuGet.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<add key="AzureFunctions@staging" value="https://azfunc.pkgs.visualstudio.com/e6a70c92-4128-439f-8012-382fe78d6396/_packaging/AzureFunctions%40staging/nuget/v3/index.json" />
1010
<add key="AzureFunctionsRelease" value="https://azfunc.pkgs.visualstudio.com/e6a70c92-4128-439f-8012-382fe78d6396/_packaging/AzureFunctionsRelease/nuget/v3/index.json" />
1111
<add key="AzureFunctionsPreRelease" value="https://azfunc.pkgs.visualstudio.com/e6a70c92-4128-439f-8012-382fe78d6396/_packaging/AzureFunctionsPreRelease/nuget/v3/index.json" />
12+
<add key="AzureFunctionsTempStaging" value="https://azfunc.pkgs.visualstudio.com/e6a70c92-4128-439f-8012-382fe78d6396/_packaging/AzureFunctionsTempStaging/nuget/v3/index.json" />
1213
<!-- dotnet-tools is required for Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.XUnit -->
1314
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json"/>
1415
</packageSources>

build/common.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<LangVersion>latest</LangVersion>
66
<MajorVersion>4</MajorVersion>
77
<MinorVersion>21</MinorVersion>
8-
<PatchVersion>0</PatchVersion>
8+
<PatchVersion>1</PatchVersion>
99
<BuildNumber Condition="'$(BuildNumber)' == '' ">0</BuildNumber>
1010
<PreviewVersion></PreviewVersion>
1111

build/python.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<Project>
22
<ItemGroup>
3-
<PackageReference Include="Microsoft.Azure.Functions.PythonWorker" Version="4.11.0" />
3+
<PackageReference Include="Microsoft.Azure.Functions.PythonWorker" Version="4.14.0" />
44
</ItemGroup>
55
</Project>

release_notes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
<!-- Please add your release notes in the following format:
44
- My change description (#PR)
55
-->
6+
- Update Python Worker Version to [4.14.0](https://github.com/Azure/azure-functions-python-worker/releases/tag/4.14.0)
67
- Update Java Worker Version to [2.11.0](https://github.com/Azure/azure-functions-java-worker/releases/tag/2.11.0)
78

89
**Release sprint:** Sprint 142
910
[ [bugs](https://github.com/Azure/azure-functions-host/issues?q=is%3Aissue+milestone%3A%22Functions+Sprint+143%22+label%3Abug+is%3Aclosed) | [features](https://github.com/Azure/azure-functions-host/issues?q=is%3Aissue+milestone%3A%22Functions+Sprint+143%22+label%3Afeature+is%3Aclosed) ]
11+
- Fixing bug with placeholder misses in dotnet-isolated #9253
12+
- (Update Python Worker Version to 4.14.0 (#9261))

src/WebJobs.Script.Grpc/Channel/GrpcWorkerChannel.cs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ internal class GrpcWorkerChannel : IRpcWorkerChannel, IDisposable
5252
private readonly IOptions<WorkerConcurrencyOptions> _workerConcurrencyOptions;
5353
private readonly WaitCallback _processInbound;
5454
private readonly object _syncLock = new object();
55+
private readonly object _metadataLock = new object();
5556
private readonly Dictionary<MsgType, Queue<PendingItem>> _pendingActions = new();
5657
private readonly ChannelWriter<OutboundGrpcEvent> _outbound;
5758
private readonly ChannelReader<InboundGrpcEvent> _inbound;
@@ -85,6 +86,7 @@ internal class GrpcWorkerChannel : IRpcWorkerChannel, IDisposable
8586
private IHttpProxyService _httpProxyService;
8687
private Uri _httpProxyEndpoint;
8788
private System.Timers.Timer _timer;
89+
private bool _functionMetadataRequestSent = false;
8890

8991
internal GrpcWorkerChannel(
9092
string workerId,
@@ -540,6 +542,8 @@ internal FunctionLoadRequestCollection GetFunctionLoadRequestCollection(IEnumera
540542
public Task SendFunctionEnvironmentReloadRequest()
541543
{
542544
_functionsIndexingTask = new TaskCompletionSource<List<RawFunctionMetadata>>(TaskCreationOptions.RunContinuationsAsynchronously);
545+
_functionMetadataRequestSent = false;
546+
543547
_workerChannelLogger.LogDebug("Sending FunctionEnvironmentReloadRequest to WorkerProcess with Pid: '{0}'", _rpcWorkerProcess.Id);
544548
IDisposable latencyEvent = _metricsLogger.LatencyEvent(MetricEventNames.SpecializationEnvironmentReloadRequestResponse);
545549

@@ -795,22 +799,32 @@ public Task<List<RawFunctionMetadata>> GetFunctionMetadata()
795799

796800
internal Task<List<RawFunctionMetadata>> SendFunctionMetadataRequest()
797801
{
798-
// reset indexing task when in case we need to send another request
799-
_functionsIndexingTask = new TaskCompletionSource<List<RawFunctionMetadata>>(TaskCreationOptions.RunContinuationsAsynchronously);
802+
_workerChannelLogger.LogDebug("Fetching worker metadata, FunctionMetadataReceived set to: {functionMetadataReceived}", _functionMetadataRequestSent);
803+
if (!_functionMetadataRequestSent)
804+
{
805+
lock (_metadataLock)
806+
{
807+
if (!_functionMetadataRequestSent)
808+
{
809+
RegisterCallbackForNextGrpcMessage(MsgType.FunctionMetadataResponse, _functionLoadTimeout, 1,
810+
msg => ProcessFunctionMetadataResponses(msg.Message.FunctionMetadataResponse), HandleWorkerMetadataRequestError);
800811

801-
RegisterCallbackForNextGrpcMessage(MsgType.FunctionMetadataResponse, _functionLoadTimeout, 1,
802-
msg => ProcessFunctionMetadataResponses(msg.Message.FunctionMetadataResponse), HandleWorkerMetadataRequestError);
812+
_workerChannelLogger.LogDebug("Sending WorkerMetadataRequest to {language} worker with worker ID {workerID}", _runtime, _workerId);
803813

804-
_workerChannelLogger.LogDebug("Sending WorkerMetadataRequest to {language} worker with worker ID {workerID}", _runtime, _workerId);
814+
// sends the function app directory path to worker for indexing
815+
SendStreamingMessage(new StreamingMessage
816+
{
817+
FunctionsMetadataRequest = new FunctionsMetadataRequest()
818+
{
819+
FunctionAppDirectory = _applicationHostOptions.CurrentValue.ScriptPath
820+
}
821+
});
805822

806-
// sends the function app directory path to worker for indexing
807-
SendStreamingMessage(new StreamingMessage
808-
{
809-
FunctionsMetadataRequest = new FunctionsMetadataRequest()
810-
{
811-
FunctionAppDirectory = _applicationHostOptions.CurrentValue.ScriptPath
823+
_functionMetadataRequestSent = true;
824+
}
812825
}
813-
});
826+
}
827+
814828
return _functionsIndexingTask.Task;
815829
}
816830

@@ -845,7 +859,8 @@ internal void ProcessFunctionMetadataResponses(FunctionMetadataResponse function
845859
FunctionDirectory = metadata.Directory,
846860
ScriptFile = metadata.ScriptFile,
847861
EntryPoint = metadata.EntryPoint,
848-
Name = metadata.Name
862+
Name = metadata.Name,
863+
Language = metadata.Language
849864
};
850865

851866
functionMetadata.SetFunctionId(metadata.FunctionId);

src/WebJobs.Script.WebHost/Models/AzureStorageInfoValue.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,12 @@ public static AzureStorageInfoValue FromEnvironmentVariable(KeyValuePair<string,
8383
}
8484

8585
var parts = environmentVariable.Value?.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
86-
if (parts == null || parts.Length != 4)
86+
if (parts == null)
87+
{
88+
return null;
89+
}
90+
91+
if (parts.Length != 4 && parts.Length != 5)
8792
{
8893
return null;
8994
}

src/WebJobs.Script.WebHost/WebHostServiceCollectionExtensions.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,9 @@ public static void AddWebJobsScriptHost(this IServiceCollection services, IConfi
175175
// Language Worker Hosted Services need to be intialized before WebJobsScriptHostService
176176
ScriptHostBuilderExtensions.AddCommonServices(services);
177177

178-
services.AddSingleton<IFunctionMetadataProvider>(sp =>
179-
{
180-
return new FunctionMetadataProvider(
181-
sp.GetRequiredService<ILogger<FunctionMetadataProvider>>(),
182-
ActivatorUtilities.CreateInstance<WorkerFunctionMetadataProvider>(sp),
183-
ActivatorUtilities.CreateInstance<HostFunctionMetadataProvider>(sp));
184-
});
178+
services.AddSingleton<IWorkerFunctionMetadataProvider, WorkerFunctionMetadataProvider>();
179+
services.AddSingleton<IHostFunctionMetadataProvider, HostFunctionMetadataProvider>();
180+
services.AddSingleton<IFunctionMetadataProvider, FunctionMetadataProvider>();
185181

186182
// Core script host services
187183
services.AddSingleton<WebJobsScriptHostService>();
@@ -208,7 +204,7 @@ public static void AddWebJobsScriptHost(this IServiceCollection services, IConfi
208204
services.AddSingleton<IOptionsChangeTokenSource<ScriptApplicationHostOptions>, ScriptApplicationHostOptionsChangeTokenSource>();
209205

210206
services.ConfigureOptions<StandbyOptionsSetup>();
211-
services.ConfigureOptions<LanguageWorkerOptionsSetup>();
207+
services.ConfigureOptionsWithChangeTokenSource<LanguageWorkerOptions, LanguageWorkerOptionsSetup, SpecializationChangeTokenSource<LanguageWorkerOptions>>();
212208
services.ConfigureOptionsWithChangeTokenSource<AppServiceOptions, AppServiceOptionsSetup, SpecializationChangeTokenSource<AppServiceOptions>>();
213209
services.ConfigureOptionsWithChangeTokenSource<HttpBodyControlOptions, HttpBodyControlOptionsSetup, SpecializationChangeTokenSource<HttpBodyControlOptions>>();
214210
services.ConfigureOptions<FunctionsHostingConfigOptionsSetup>();

src/WebJobs.Script/Config/FunctionsHostingConfigOptions.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,28 @@ public bool WorkerWarmupEnabled
4343
}
4444
}
4545

46+
/// <summary>
47+
/// Gets a value indicating whether worker indexing feature is enabled in the hosting config.
48+
/// </summary>
49+
public bool WorkerIndexingEnabled
50+
{
51+
get
52+
{
53+
return GetFeature(RpcWorkerConstants.WorkerIndexingEnabled) == "1";
54+
}
55+
}
56+
57+
/// <summary>
58+
/// Gets a string delimited by '|' that contains the name of the apps with worker indexing disabled.
59+
/// </summary>
60+
public string WorkerIndexingDisabledApps
61+
{
62+
get
63+
{
64+
return GetFeature(RpcWorkerConstants.WorkerIndexingDisabledApps) ?? string.Empty;
65+
}
66+
}
67+
4668
/// <summary>
4769
/// Gets a value indicating whether Linux Log Backoff is disabled in the hosting config.
4870
/// </summary>

src/WebJobs.Script/DependencyInjection/ScriptStartupTypeLocator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public async Task<IEnumerable<Type>> GetExtensionsStartupTypesAsync()
8989
ExtensionBundleDetails bundleDetails = await _extensionBundleManager.GetExtensionBundleDetails();
9090
ValidateBundleRequirements(bundleDetails);
9191

92-
var functionMetadataCollection = _functionMetadataManager.GetFunctionMetadata(forceRefresh: true, includeCustomProviders: false);
92+
var functionMetadataCollection = _functionMetadataManager.GetFunctionMetadata(forceRefresh: true, includeCustomProviders: false, workerConfigs: workerConfigs);
9393
bindingsSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
9494

9595
// Generate a Hashset of all the binding types used in the function app

src/WebJobs.Script/Host/FunctionMetadataManager.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,15 @@ public class FunctionMetadataManager : IFunctionMetadataManager
3030
private bool _servicesReset = false;
3131
private ILogger _logger;
3232
private IOptions<ScriptJobHostOptions> _scriptOptions;
33-
private IOptionsMonitor<LanguageWorkerOptions> _languageWorkerOptions;
3433
private ImmutableArray<FunctionMetadata> _functionMetadataArray;
3534
private Dictionary<string, ICollection<string>> _functionErrors = new Dictionary<string, ICollection<string>>();
3635
private ConcurrentDictionary<string, FunctionMetadata> _functionMetadataMap = new ConcurrentDictionary<string, FunctionMetadata>(StringComparer.OrdinalIgnoreCase);
3736

3837
public FunctionMetadataManager(IOptions<ScriptJobHostOptions> scriptOptions, IFunctionMetadataProvider functionMetadataProvider,
3938
IOptions<HttpWorkerOptions> httpWorkerOptions, IScriptHostManager scriptHostManager, ILoggerFactory loggerFactory,
40-
IOptionsMonitor<LanguageWorkerOptions> languageWorkerOptions, IEnvironment environment)
39+
IEnvironment environment)
4140
{
4241
_scriptOptions = scriptOptions;
43-
_languageWorkerOptions = languageWorkerOptions;
4442
_serviceProvider = scriptHostManager as IServiceProvider;
4543
_functionMetadataProvider = functionMetadataProvider;
4644
_loggerFactory = loggerFactory;
@@ -84,11 +82,11 @@ public bool TryGetFunctionMetadata(string functionName, out FunctionMetadata fun
8482
/// <param name="applyAllowList">Apply functions allow list filter.</param>
8583
/// <param name="includeCustomProviders">Include any metadata provided by IFunctionProvider when loading the metadata</param>
8684
/// <returns> An Immmutable array of FunctionMetadata.</returns>
87-
public ImmutableArray<FunctionMetadata> GetFunctionMetadata(bool forceRefresh, bool applyAllowList = true, bool includeCustomProviders = true)
85+
public ImmutableArray<FunctionMetadata> GetFunctionMetadata(bool forceRefresh, bool applyAllowList = true, bool includeCustomProviders = true, IList<RpcWorkerConfig> workerConfigs = null)
8886
{
8987
if (forceRefresh || _servicesReset || _functionMetadataArray.IsDefaultOrEmpty)
9088
{
91-
_functionMetadataArray = LoadFunctionMetadata(forceRefresh, includeCustomProviders);
89+
_functionMetadataArray = LoadFunctionMetadata(forceRefresh, includeCustomProviders, workerConfigs: workerConfigs);
9290
_logger.FunctionMetadataManagerFunctionsLoaded(ApplyAllowList(_functionMetadataArray).Count());
9391
_servicesReset = false;
9492
}
@@ -114,28 +112,37 @@ private void InitializeServices()
114112

115113
_isHttpWorker = _serviceProvider.GetService<IOptions<HttpWorkerOptions>>()?.Value?.Description != null;
116114
_scriptOptions = _serviceProvider.GetService<IOptions<ScriptJobHostOptions>>();
117-
_languageWorkerOptions = _serviceProvider.GetService<IOptionsMonitor<LanguageWorkerOptions>>();
118115

119116
// Resetting the logger switches the logger scope to Script Host level,
120117
// also making the logs available to Application Insights
121118
_logger = _serviceProvider?.GetService<ILoggerFactory>().CreateLogger(LogCategories.Startup);
122119
_servicesReset = true;
123120
}
124121

122+
/// <summary>
123+
/// This is the worker configuration created in the jobhost scope during placeholder initialization
124+
/// This is used as a fallback incase the config is not passed down from previous method call.
125+
/// </summary>
126+
private IList<RpcWorkerConfig> GetFallbackWorkerConfig()
127+
{
128+
return _serviceProvider.GetService<IOptionsMonitor<LanguageWorkerOptions>>().CurrentValue.WorkerConfigs;
129+
}
130+
125131
/// <summary>
126132
/// Read all functions and populate function metadata.
127133
/// </summary>
128-
internal ImmutableArray<FunctionMetadata> LoadFunctionMetadata(bool forceRefresh = false, bool includeCustomProviders = true, IFunctionInvocationDispatcher dispatcher = null)
134+
internal ImmutableArray<FunctionMetadata> LoadFunctionMetadata(bool forceRefresh = false, bool includeCustomProviders = true, IFunctionInvocationDispatcher dispatcher = null, IList<RpcWorkerConfig> workerConfigs = null)
129135
{
136+
workerConfigs ??= GetFallbackWorkerConfig();
137+
130138
_functionMetadataMap.Clear();
131139

132140
ICollection<string> functionsAllowList = _scriptOptions?.Value?.Functions;
133141
_logger.FunctionMetadataManagerLoadingFunctionsMetadata();
134142

135143
ImmutableArray<FunctionMetadata> immutableFunctionMetadata;
136-
var workerConfigs = _languageWorkerOptions.CurrentValue.WorkerConfigs;
137144

138-
immutableFunctionMetadata = _functionMetadataProvider.GetFunctionMetadataAsync(workerConfigs, SystemEnvironment.Instance, forceRefresh).GetAwaiter().GetResult();
145+
immutableFunctionMetadata = _functionMetadataProvider.GetFunctionMetadataAsync(workerConfigs, _environment, forceRefresh).GetAwaiter().GetResult();
139146

140147
var functionMetadataList = new List<FunctionMetadata>();
141148
_functionErrors = new Dictionary<string, ICollection<string>>();

0 commit comments

Comments
 (0)