Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion build/common.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<LangVersion>latest</LangVersion>
<MajorVersion>4</MajorVersion>
<MinorVersion>27</MinorVersion>
<PatchVersion>4</PatchVersion>
<PatchVersion>5</PatchVersion>
<BuildNumber Condition="'$(BuildNumber)' == '' ">0</BuildNumber>
<PreviewVersion></PreviewVersion>

Expand Down
13 changes: 4 additions & 9 deletions release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,11 @@
-->
- Update Python Worker Version to [4.20.0](https://github.com/Azure/azure-functions-python-worker/releases/tag/4.20.0)
- Update Java Worker Version to [2.13.0](https://github.com/Azure/azure-functions-java-worker/releases/tag/2.13.0)
- Update WebJobsScriptHostService to remove hardcoded sleep during application shut down (#9520)
- Increased maximum HTTP request content size to 210000000 Bytes (~200MB)
- Update Node.js Worker Version to [3.8.1](https://github.com/Azure/azure-functions-nodejs-worker/releases/tag/v3.8.1)
- Update PowerShell 7.4 Worker Version to [4.0.2975](https://github.com/Azure/azure-functions-powershell-worker/releases/tag/v4.0.2975)
- Update PowerShell 7.2 Worker Version to [4.0.2974](https://github.com/Azure/azure-functions-powershell-worker/releases/tag/v4.0.2974)
- Update PowerShell 7.0 Worker Version to [4.0.2973](https://github.com/Azure/azure-functions-powershell-worker/releases/tag/v4.0.2973)
- Add support for standalone executable (ie: `dotnet build --standalone`) for out-of-proc workers in Linux Consumption. (#9550)
- Bug fix: Do not restart worker channels or JobHost when an API request is made to get or update the function metadata (unless the config was changed) (#9510)
- This fixes a bug where requests to 'admin/functions' lead to a "Did not find initialized workers" error when
worker indexing is enabled.
- Bug fix: If there are no channels created and the host is running, restart the JobHost instead of shutting down worker channels (#9510)
- 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)
- Sending command line arguments to language workers with `functions-` prefix to prevent conflicts (#9514)
- Update WebJobsScriptHostService to remove hardcoded sleep during application shut down (#9520)
27 changes: 21 additions & 6 deletions src/WebJobs.Script.Grpc/Channel/GrpcWorkerChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,12 +374,18 @@ internal void FunctionEnvironmentReloadResponse(FunctionEnvironmentReloadRespons

ApplyCapabilities(res.Capabilities, res.CapabilitiesUpdateStrategy.ToGrpcCapabilitiesUpdateStrategy());

if (res.Result.IsFailure(out Exception reloadEnvironmentVariablesException))
if (res.Result.IsFailure(IsUserCodeExceptionCapabilityEnabled(), out var reloadEnvironmentVariablesException))
{
_workerChannelLogger.LogError(reloadEnvironmentVariablesException, "Failed to reload environment variables");
_reloadTask.SetException(reloadEnvironmentVariablesException);
if (res.Result.Exception is not null && reloadEnvironmentVariablesException is not null)
{
_workerChannelLogger.LogWarning(reloadEnvironmentVariablesException, reloadEnvironmentVariablesException.Message);
}
_reloadTask.SetResult(false);
}
else
{
_reloadTask.SetResult(true);
}
_reloadTask.SetResult(true);
latencyEvent.Dispose();
}

Expand Down Expand Up @@ -414,6 +420,15 @@ internal void WorkerInitResponse(GrpcEvent initEvent)
_workerInitTask.TrySetResult(true);
}

private bool IsUserCodeExceptionCapabilityEnabled()
{
var enableUserCodeExceptionCapability = string.Equals(
_workerCapabilities.GetCapabilityState(RpcWorkerConstants.EnableUserCodeException), bool.TrueString,
StringComparison.OrdinalIgnoreCase);

return enableUserCodeExceptionCapability;
}

private void LogWorkerMetadata(WorkerMetadata workerMetadata)
{
if (workerMetadata == null)
Expand Down Expand Up @@ -546,7 +561,7 @@ internal FunctionLoadRequestCollection GetFunctionLoadRequestCollection(IEnumera
return functionLoadRequestCollection;
}

public Task SendFunctionEnvironmentReloadRequest()
public Task<bool> SendFunctionEnvironmentReloadRequest()
{
_functionsIndexingTask = new TaskCompletionSource<List<RawFunctionMetadata>>(TaskCreationOptions.RunContinuationsAsynchronously);
_functionMetadataRequestSent = false;
Expand Down Expand Up @@ -1576,4 +1591,4 @@ private void OnTimeout()
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@

using System;
using System.Threading.Tasks;
using Grpc.Core;
using Microsoft.Azure.WebJobs.Script.Config;
using Microsoft.Azure.WebJobs.Script.Grpc.Messages;

namespace Microsoft.Azure.WebJobs.Script.Grpc
{
internal static class StatusResultExtensions
{
public static bool IsFailure(this StatusResult statusResult, out Exception exception)
public static bool IsFailure(this StatusResult statusResult, bool enableUserCodeExceptionCapability, out Exception exception)
{
switch (statusResult.Status)
{
case StatusResult.Types.Status.Failure:
exception = GetRpcException(statusResult);
exception = GetRpcException(statusResult, enableUserCodeExceptionCapability);
return true;

case StatusResult.Types.Status.Cancelled:
Expand All @@ -29,6 +27,11 @@ public static bool IsFailure(this StatusResult statusResult, out Exception excep
}
}

public static bool IsFailure(this StatusResult statusResult, out Exception exception)
{
return IsFailure(statusResult, false, out exception);
}

/// <summary>
/// This method is only hit on the invocation code path.
/// enableUserCodeExceptionCapability = feature flag exposed as a capability that is set by the worker.
Expand Down Expand Up @@ -68,4 +71,4 @@ public static Workers.Rpc.RpcException GetRpcException(StatusResult statusResult
return new Workers.Rpc.RpcException(status, string.Empty, string.Empty);
}
}
}
}
7 changes: 6 additions & 1 deletion src/WebJobs.Script/Environment/IEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ namespace Microsoft.Azure.WebJobs.Script
/// </summary>
public interface IEnvironment
{
/// <summary>
/// Gets a value indicating whether the current process is a 64-bit process.
/// </summary>
public bool Is64BitProcess { get; }

/// <summary>
/// Returns the value of an environment variable for the current <see cref="IEnvironment"/>.
/// </summary>
Expand All @@ -20,7 +25,7 @@ public interface IEnvironment
string GetEnvironmentVariable(string name);

/// <summary>
/// Creates, modifies, or deletes an environment variable stored in the current <see cref="IEnvironment"/>
/// Creates, modifies, or deletes an environment variable stored in the current <see cref="IEnvironment"/>.
/// </summary>
/// <param name="name">The environment variable name.</param>
/// <param name="value">The value to assign to the variable.</param>
Expand Down
2 changes: 2 additions & 0 deletions src/WebJobs.Script/Environment/SystemEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ private SystemEnvironment()

public static SystemEnvironment Instance => _instance.Value;

public bool Is64BitProcess => Environment.Is64BitProcess;

private static SystemEnvironment CreateInstance()
{
return new SystemEnvironment();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public bool IsLegacyExtensionBundle()
/// <summary>
/// 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.
/// </summary>
/// <returns>Path of the extension bundle</returns>
/// <returns>Path of the extension bundle.</returns>
public async Task<string> GetExtensionBundlePath()
{
using (var httpClient = new HttpClient())
Expand All @@ -83,8 +83,8 @@ public async Task<string> GetExtensionBundlePath()
/// <summary>
/// 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.
/// </summary>
/// <param name="httpClient">HttpClient used to download the extension bundle</param>
/// <returns>Path of the extension bundle</returns>
/// <param name="httpClient">HttpClient used to download the extension bundle.</param>
/// <returns>Path of the extension bundle.</returns>
public async Task<string> GetExtensionBundlePath(HttpClient httpClient)
{
return await GetBundle(httpClient);
Expand Down
1 change: 1 addition & 0 deletions src/WebJobs.Script/ScriptConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
10 changes: 5 additions & 5 deletions src/WebJobs.Script/WebJobs.Script.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.21.0" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer" Version="2.21.0" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" Version="2.21.0" />
<PackageReference Include="Microsoft.Azure.Functions.DotNetIsolatedNativeHost" Version="1.0.0-preview805" />
<PackageReference Include="Microsoft.Azure.Functions.DotNetIsolatedNativeHost" Version="1.0.2" />
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.39" />
<PackageReference Include="Microsoft.Azure.WebJobs.Host.Storage" Version="5.0.0-beta.2-11957" />
<PackageReference Include="Microsoft.Extensions.Azure" Version="1.7.0" />
Expand All @@ -57,11 +57,11 @@

<!-- Workers -->
<PackageReference Include="Microsoft.Azure.AppService.Proxy.Client" Version="2.2.20220831.41" />
<PackageReference Include="Microsoft.Azure.Functions.JavaWorker" Version="2.12.1" />
<PackageReference Include="Microsoft.Azure.Functions.JavaWorker" Version="2.13.0" />
<PackageReference Include="Microsoft.Azure.Functions.NodeJsWorker" Version="3.8.1" />
<PackageReference Include="Microsoft.Azure.Functions.PowerShellWorker.PS7.0" Version="4.0.2850" />
<PackageReference Include="Microsoft.Azure.Functions.PowerShellWorker.PS7.2" Version="4.0.2890" />
<PackageReference Include="Microsoft.Azure.Functions.PowerShellWorker.PS7.4" Version="4.0.2930" />
<PackageReference Include="Microsoft.Azure.Functions.PowerShellWorker.PS7.0" Version="4.0.2973" />
<PackageReference Include="Microsoft.Azure.Functions.PowerShellWorker.PS7.2" Version="4.0.2974" />
<PackageReference Include="Microsoft.Azure.Functions.PowerShellWorker.PS7.4" Version="4.0.2975" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="5.0.0-beta.2-10879" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="3.2.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Timers.Storage" Version="1.0.0-beta.1" />
Expand Down
2 changes: 1 addition & 1 deletion src/WebJobs.Script/Workers/Rpc/IRpcWorkerChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public interface IRpcWorkerChannel : IWorkerChannel

void SendFunctionLoadRequests(ManagedDependencyOptions managedDependencyOptions, TimeSpan? functionTimeout);

Task SendFunctionEnvironmentReloadRequest();
Task<bool> SendFunctionEnvironmentReloadRequest();

void SendWorkerWarmupRequest();

Expand Down
5 changes: 4 additions & 1 deletion src/WebJobs.Script/Workers/Rpc/RpcWorkerContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ public RpcWorkerContext(string requestId,

public override string GetFormattedArguments()
{
return $" --host {ServerUri.Host} --port {ServerUri.Port} --workerId {WorkerId} --requestId {RequestId} --grpcMaxMessageLength {MaxMessageLength}";
// Adding a second copy of the commandline arguments with the "functions-" prefix to prevent any conflicts caused by the existing generic names.
// Language workers are advised to use the "functions-" prefix ones and if not present fallback to existing ones.

return $" --host {ServerUri.Host} --port {ServerUri.Port} --workerId {WorkerId} --requestId {RequestId} --grpcMaxMessageLength {MaxMessageLength} --functions-uri {ServerUri.AbsoluteUri} --functions-worker-id {WorkerId} --functions-request-id {RequestId} --functions-grpc-max-message-length {MaxMessageLength}";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,14 @@ public async Task SpecializeAsync()

if (_workerRuntime != null && rpcWorkerChannel != null)
{
bool envReloadRequestResultSuccessful = false;
if (UsePlaceholderChannel(rpcWorkerChannel))
{
_logger.LogDebug("Loading environment variables for runtime: {runtime}", _workerRuntime);
await rpcWorkerChannel.SendFunctionEnvironmentReloadRequest();
envReloadRequestResultSuccessful = await rpcWorkerChannel.SendFunctionEnvironmentReloadRequest();
}
else

if (envReloadRequestResultSuccessful == false)
{
_logger.LogDebug("Shutting down placeholder worker. Worker is not compatible for runtime: {runtime}", _workerRuntime);
// If we need to allow file edits, we should shutdown the webhost channel on specialization.
Expand Down Expand Up @@ -181,6 +183,15 @@ private bool UsePlaceholderChannel(IRpcWorkerChannel channel)
return false;
}

// We support specialization of dotnet-isolated only on 64bit host process.
if (!_environment.Is64BitProcess)
{
_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;
}

// 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);
Expand Down
10 changes: 6 additions & 4 deletions test/DotNetIsolated60/DotNetIsolated60.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<FunctionsEnableWorkerIndexing>True</FunctionsEnableWorkerIndexing>
<FunctionsAutoRegisterGeneratedMetadataProvider>True</FunctionsAutoRegisterGeneratedMetadataProvider>
<FunctionsEnableExecutorSourceGen>True</FunctionsEnableExecutorSourceGen>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.18.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.0.0-preview2" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.19.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage" Version="6.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.12.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.15.1" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
Expand Down
6 changes: 6 additions & 0 deletions test/DotNetIsolated60/DotNetIsolated60.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ VisualStudioVersion = 17.5.33627.172
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetIsolated60", "DotNetIsolated60.csproj", "{1DA92227-F28E-408D-96B1-20C72571E4AE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetIsolatedUnsupportedWorker", "..\DotNetIsolatedUnsupportedWorker\DotNetIsolatedUnsupportedWorker.csproj", "{3F15B936-6365-447E-9EC6-4E996B30C55F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -15,6 +17,10 @@ Global
{1DA92227-F28E-408D-96B1-20C72571E4AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1DA92227-F28E-408D-96B1-20C72571E4AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1DA92227-F28E-408D-96B1-20C72571E4AE}.Release|Any CPU.Build.0 = Release|Any CPU
{3F15B936-6365-447E-9EC6-4E996B30C55F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F15B936-6365-447E-9EC6-4E996B30C55F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F15B936-6365-447E-9EC6-4E996B30C55F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F15B936-6365-447E-9EC6-4E996B30C55F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
6 changes: 2 additions & 4 deletions test/DotNetIsolated60/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,12 @@
if (useProxy)
{
hostBuilder
.ConfigureFunctionsWebApplication()
.ConfigureGeneratedFunctionMetadataProvider();
.ConfigureFunctionsWebApplication();
}
else
{
hostBuilder
.ConfigureFunctionsWorkerDefaults()
.ConfigureGeneratedFunctionMetadataProvider();
.ConfigureFunctionsWorkerDefaults();
}

var host = hostBuilder.Build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<FunctionsEnableWorkerIndexing>True</FunctionsEnableWorkerIndexing>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.19.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage" Version="6.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.14.0" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
</ItemGroup>
</Project>
Loading