Skip to content

Commit 56fb132

Browse files
committed
Merge branch 'dev' into jviau/abort-channel
2 parents da70f86 + 006d6bb commit 56fb132

File tree

49 files changed

+1171
-144
lines changed

Some content is hidden

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

49 files changed

+1171
-144
lines changed

eng/build/Workers.Powershell.props

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@
88

99
<Target Name="RemovePowershellWorkerRuntimes" BeforeTargets="AssignTargetPaths" Condition="'$(RuntimeIdentifier)' != ''">
1010
<ItemGroup>
11-
<_KeepPowerShellRuntime Include="win;win-x86;win10-x86;win-x64;win10-x64" Condition="$(RuntimeIdentifier.StartsWith(win))" />
12-
<_KeepPowerShellRuntime Include="linux;linux-x64;unix" Condition="$(RuntimeIdentifier.StartsWith(linux))" />
11+
<_KeepPowerShellRuntime Include="win;win-x86;win10-x86;win-x64;win10-x64" Condition="$(RuntimeIdentifier.StartsWith('win')) and !$(RuntimeIdentifier.Contains('arm'))" />
12+
<_KeepPowerShellRuntime Include="win;win-arm;win-arm64" Condition="'$(RuntimeIdentifier)' == 'win-arm64'" />
13+
14+
<_KeepPowerShellRuntime Include="linux;unix;linux-x64" Condition="'$(RuntimeIdentifier)' == 'linux-x64'" />
15+
<_KeepPowerShellRuntime Include="linux;unix;linux-arm;linux-arm64" Condition="'$(RuntimeIdentifier)' == 'linux-arm64'" />
16+
17+
<_KeepPowerShellRuntime Include="osx;unix;osx-x64" Condition="'$(RuntimeIdentifier)' == 'osx-x64'" />
18+
<_KeepPowerShellRuntime Include="osx;unix;osx-arm64" Condition="'$(RuntimeIdentifier)' == 'osx-arm64'" />
1319
</ItemGroup>
1420

1521
<PropertyGroup>

eng/build/Workers.Python.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<ItemGroup>
44
<!-- Python worker does not ship with the host for windows. -->
5-
<PackageReference Include="Microsoft.Azure.Functions.PythonWorker" Version="4.36.1" Condition="!$(RuntimeIdentifier.StartsWith('win'))" />
5+
<PackageReference Include="Microsoft.Azure.Functions.PythonWorker" Version="4.37.0" Condition="!$(RuntimeIdentifier.StartsWith('win'))" />
66
</ItemGroup>
77

88
</Project>

eng/ci/host.metrics-monitor.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# No triggers for code push to any branch.
2+
trigger: none
3+
4+
# No PR triggers.
5+
pr: none
6+
7+
schedules:
8+
- cron: "0 6,18 * * *"
9+
displayName: Daily Schedule (6 AM & 6 PM UTC)
10+
branches:
11+
include:
12+
- dev
13+
always: true
14+
15+
resources:
16+
repositories:
17+
- repository: 1es
18+
type: git
19+
name: 1ESPipelineTemplates/1ESPipelineTemplates
20+
ref: refs/tags/release
21+
- repository: eng
22+
type: git
23+
name: engineering
24+
ref: refs/tags/release
25+
26+
variables:
27+
- template: /ci/variables/cfs.yml@eng
28+
29+
extends:
30+
template: v1/1ES.Unofficial.PipelineTemplate.yml@1es
31+
parameters:
32+
pool:
33+
name: 1es-pool-azfunc-benchmarking
34+
image: 1es-windows-2022-benchmark-runner-vanilla
35+
os: windows
36+
37+
stages:
38+
- stage: RunWindows
39+
displayName: Collect Windows metrics
40+
jobs:
41+
- template: /eng/ci/templates/official/jobs/run-metrics-monitor.yml@self
42+
parameters:
43+
description: .NET9 Timer Application
44+
functionAppName: TimerAppNet9
45+
azureMonitorConnectionString: $(WINDOWS_AZURE_MONITOR_CONNECTION)
46+
47+
- stage: RunLinux
48+
dependsOn: []
49+
displayName: Collect Linux metrics
50+
jobs:
51+
- template: /eng/ci/templates/official/jobs/run-metrics-monitor.yml@self
52+
parameters:
53+
os: Linux
54+
description: .NET9 Timer Application
55+
functionAppName: TimerAppNet9
56+
azureMonitorConnectionString: $(LINUX_AZURE_MONITOR_CONNECTION)
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
parameters:
2+
- name: description
3+
type: string
4+
- name: functionAppName
5+
type: string
6+
- name: os
7+
type: string
8+
default: Windows
9+
values:
10+
- Windows
11+
- Linux
12+
- name: azureMonitorConnectionString
13+
type: string
14+
15+
jobs:
16+
- job: ${{ parameters.functionAppName }}_${{ parameters.os }}
17+
displayName: ${{ parameters.os }} ${{ parameters.description }}
18+
pool:
19+
name: 1es-pool-azfunc-benchmarking
20+
${{ if eq(parameters.os, 'Linux') }}:
21+
image: 1es-ubuntu-22.04-benchmark-runner-vanilla
22+
os: linux
23+
${{ else }}:
24+
image: 1es-windows-2022-benchmark-runner-vanilla
25+
os: windows
26+
27+
variables:
28+
functionAppOutputPath: $(Build.BinariesDirectory)/Published/${{ parameters.functionAppName }}
29+
hostOutputPath: $(Build.BinariesDirectory)/Published/HostRuntime
30+
hostAssemblyPath: $(hostOutputPath)/Microsoft.Azure.WebJobs.Script.WebHost.dll
31+
logsDirectory: $(Build.ArtifactStagingDirectory)/Logs
32+
stdOutLogsFilePath: $(logsDirectory)/std_out_logs.txt
33+
stdErrorLogsFilePath: $(logsDirectory)/std_error_logs.txt
34+
FUNCTIONS_WORKER_RUNTIME: 'dotnet-isolated'
35+
FUNCTIONS_WORKER_RUNTIME_VERSION: '9.0'
36+
AzureFunctionsWebHost__hostid: '${{ parameters.functionAppName }}_${{ parameters.os }}'
37+
AzureWebJobsScriptRoot: '$(functionAppOutputPath)'
38+
${{ if eq(parameters.os, 'Linux') }}:
39+
publishRid: linux-x64
40+
${{ if eq(parameters.os, 'Windows') }}:
41+
publishRid: win-x64
42+
43+
steps:
44+
- template: /eng/ci/templates/install-dotnet.yml@self
45+
46+
- task: CopyFiles@2
47+
displayName: Copy benchmark apps to temp location
48+
inputs:
49+
SourceFolder: '$(Build.SourcesDirectory)/test/Performance/Apps'
50+
Contents: '**/*'
51+
TargetFolder: '$(Build.ArtifactStagingDirectory)/PerformanceTestApps'
52+
CleanTargetFolder: true
53+
54+
- task: DotNetCoreCLI@2
55+
displayName: Publish function app
56+
inputs:
57+
command: publish
58+
publishWebProjects: false
59+
zipAfterPublish: false
60+
modifyOutputPath: false
61+
projects: '$(Build.ArtifactStagingDirectory)/PerformanceTestApps/${{ parameters.functionAppName }}/App.csproj'
62+
arguments: -c Release -o $(functionAppOutputPath) -f net9.0 -r $(publishRid)
63+
workingDirectory: $(Build.ArtifactStagingDirectory)/PerformanceTestApps/${{ parameters.functionAppName }}
64+
65+
- task: DotNetCoreCLI@2
66+
displayName: Publish host
67+
inputs:
68+
command: publish
69+
publishWebProjects: false
70+
zipAfterPublish: false
71+
modifyOutputPath: false
72+
projects: '$(Build.SourcesDirectory)/src/WebJobs.Script.WebHost/WebJobs.Script.WebHost.csproj'
73+
arguments: -c Release -o $(hostOutputPath) -r $(publishRid) -f net8.0 -p:PlaceholderSimulation=true
74+
workingDirectory: $(Build.SourcesDirectory)/src/WebJobs.Script.WebHost
75+
76+
- pwsh: |
77+
Write-Host "Creating log directory: $(logsDirectory)"
78+
New-Item -ItemType Directory -Path $(logsDirectory)
79+
displayName: Create log directories
80+
81+
- ${{ if eq(parameters.os, 'Windows') }}:
82+
- pwsh: |
83+
$env:APPLICATIONINSIGHTS_CONNECTION_STRING = "${env:AZ_MON_CONNECTION_STRING}"
84+
$errorLogFilePath = "$(Build.ArtifactStagingDirectory)/Logs/std_err_logs.txt"
85+
$process = Start-Process -FilePath "$(hostOutputPath)/Microsoft.Azure.WebJobs.Script.WebHost.exe" -RedirectStandardOutput $(stdOutLogsFilePath) -RedirectStandardError $(stdErrorLogsFilePath) -PassThru
86+
Write-Host "Started process ID: $($process.Id)"
87+
echo $process.Id > $(Build.ArtifactStagingDirectory)/hostProcessId.txt
88+
displayName: Start functions host
89+
env:
90+
AZ_MON_CONNECTION_STRING: ${{ parameters.azureMonitorConnectionString }}
91+
- ${{ else }}:
92+
- script: |
93+
# In Azure DevOps, when variables convert into environment variables, variable names become uppercase, and periods turn into underscores.
94+
# This works for windows when getting the env variable value, but fails on linux. So we need to pass the variable value using correct case.
95+
# https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#environment-variables
96+
export AzureWebJobsScriptRoot="$(functionAppOutputPath)"
97+
export APPLICATIONINSIGHTS_CONNECTION_STRING="$AZ_MON_CONNECTION_STRING"
98+
nohup dotnet $(hostAssemblyPath) > $(stdOutLogsFilePath) 2> $(stdErrorLogsFilePath) &
99+
echo $! > $(Build.ArtifactStagingDirectory)/hostProcessId.txt
100+
displayName: Start functions host
101+
env:
102+
AZ_MON_CONNECTION_STRING: ${{ parameters.azureMonitorConnectionString }}
103+
104+
- pwsh: |
105+
$url = "http://localhost:5000/api/warmup"
106+
Write-Host "Checking if host is ready at $url..."
107+
$maxAttempts = 5
108+
109+
for ($attempt = 0; $attempt -lt $maxAttempts; $attempt++) {
110+
try {
111+
$response = Invoke-RestMethod -Uri $url -Method Get -TimeoutSec 5 -ErrorAction Stop
112+
Write-Host "Response: $response"
113+
break
114+
} catch {
115+
Write-Host "Attempt $($attempt+1) failed: $_.Exception.Message. Retrying in 10 seconds..."
116+
Start-Sleep -Seconds 10
117+
}
118+
}
119+
displayName: Wait until host is ready
120+
121+
- pwsh: |
122+
$helloUrl = "http://localhost:5000?forcespecialization=1"
123+
Write-Host "Calling $helloUrl"
124+
Invoke-WebRequest -Uri $helloUrl -Method Get -ErrorAction Stop
125+
displayName: Specialize
126+
127+
- pwsh: |
128+
$appRunDurationInSeconds = $env:RUN_DURATION_IN_SECONDS
129+
Start-Sleep -Seconds $appRunDurationInSeconds
130+
displayName: Run for $(APP_RUN_DURATION_IN_SECONDS) seconds
131+
env:
132+
RUN_DURATION_IN_SECONDS: $(APP_RUN_DURATION_IN_SECONDS)
133+
134+
- ${{ if eq(parameters.os, 'Windows') }}:
135+
- pwsh: |
136+
$processIdFile = "$(Build.ArtifactStagingDirectory)/hostProcessId.txt"
137+
if (Test-Path $processIdFile) {
138+
$processId = Get-Content $processIdFile
139+
Write-Host "Stop functions host process with process ID: $processId"
140+
Stop-Process -Id $processId -Force
141+
} else {
142+
Write-Host "Process ID file not found."
143+
}
144+
displayName: Stop host process
145+
condition: always()
146+
147+
- ${{ if eq(parameters.os, 'Linux') }}:
148+
- script: |
149+
processIdFile="$(Build.ArtifactStagingDirectory)/hostProcessId.txt"
150+
if [ -f "$processIdFile" ]; then
151+
processId=$(cat $processIdFile)
152+
echo "Sending SIGTERM to functions host process process ID: $processId"
153+
kill -SIGTERM $processId
154+
else
155+
echo "Process ID file not found."
156+
fi
157+
displayName: Stop host process
158+
condition: always()
159+
160+
- pwsh: |
161+
Write-Host "Logs:"
162+
Get-Content $(stdOutLogsFilePath)
163+
Write-Host "----"
164+
Write-Host "Error logs:"
165+
Get-Content $(stdErrorLogsFilePath)
166+
displayName: Print logs
167+
condition: always()

release_notes.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,5 @@
33
<!-- Please add your release notes in the following format:
44
- My change description (#PR)
55
-->
6-
- Improved memory metrics reporting using CGroup data for Linux consumption (#10968)
7-
- Memory allocation optimizations in `RpcWorkerConfigFactory.AddProviders` (#10959)
8-
- Fixing GrpcWorkerChannel concurrency bug (#10998)
9-
- Avoid circular dependency when resolving LinuxContainerLegionMetricsPublisher. (#10991)
10-
- Add 'unix' to the list of runtimes kept when importing PowerShell worker for Linux builds
11-
- Update PowerShell 7.4 worker to 4.0.4206
6+
- Memory allocation optimizations in `ScriptStartupTypeLocator.GetExtensionsStartupTypesAsync` (#11012)
7+
- Fix invocation timeout when incoming request contains "x-ms-invocation-id" header (#10980)

src/Directory.Version.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<VersionPrefix>4.1040.100</VersionPrefix>
3+
<VersionPrefix>4.1041.100</VersionPrefix>
44
<UpdateBuildNumber>true</UpdateBuildNumber>
55
</PropertyGroup>
66
</Project>

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ internal async Task SendInvocationRequest(ScriptInvocationContext context)
905905
}
906906

907907
var invocationRequest = await context.ToRpcInvocationRequest(_workerChannelLogger, _workerCapabilities, _isSharedMemoryDataTransferEnabled, _sharedMemoryManager);
908-
AddAdditionalTraceContext(invocationRequest.TraceContext.Attributes, context);
908+
AddAdditionalTraceContext(invocationRequest, context);
909909
_executingInvocations.TryAdd(invocationRequest.InvocationId, new(context, _messageDispatcherFactory.Create(invocationRequest.InvocationId)));
910910
_metricsLogger.LogEvent(string.Format(MetricEventNames.WorkerInvoked, Id), functionName: Sanitizer.Sanitize(context.FunctionMetadata.Name));
911911

@@ -1697,8 +1697,9 @@ private void AddSample<T>(List<T> samples, T sample)
16971697
}
16981698
}
16991699

1700-
private void AddAdditionalTraceContext(MapField<string, string> attributes, ScriptInvocationContext context)
1700+
private void AddAdditionalTraceContext(InvocationRequest invocationRequest, ScriptInvocationContext context)
17011701
{
1702+
MapField<string, string> attributes = invocationRequest.TraceContext.Attributes;
17021703
bool isOtelEnabled = _scriptHostOptions?.Value.TelemetryMode == TelemetryMode.OpenTelemetry;
17031704
bool isAIEnabled = _environment.IsApplicationInsightsAgentEnabled();
17041705

@@ -1738,6 +1739,7 @@ private void AddAdditionalTraceContext(MapField<string, string> attributes, Scri
17381739
if (isOtelEnabled)
17391740
{
17401741
Activity.Current?.AddTag(ResourceSemanticConventions.FaaSName, context.FunctionMetadata.Name);
1742+
Activity.Current?.AddTag(ResourceSemanticConventions.FaaSInvocationId, invocationRequest.InvocationId);
17411743
}
17421744
}
17431745

src/WebJobs.Script.Grpc/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55

66
[assembly: InternalsVisibleTo("Microsoft.Azure.WebJobs.Script.Benchmarks")]
77
[assembly: InternalsVisibleTo("Microsoft.Azure.WebJobs.Script.Tests")]
8-
[assembly: InternalsVisibleTo("Microsoft.Azure.WebJobs.Script.Tests.Integration")]
8+
[assembly: InternalsVisibleTo("Microsoft.Azure.WebJobs.Script.Tests.Integration")]
9+
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

src/WebJobs.Script.Grpc/Server/DefaultHttpProxyService.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using System;
5-
using System.Collections.Generic;
65
using System.Linq;
76
using System.Net.Http;
87
using System.Threading.Tasks;
@@ -96,8 +95,8 @@ public void StartForwarding(ScriptInvocationContext context, Uri httpUri)
9695
HttpContext httpContext = httpRequest.HttpContext;
9796
httpContext.Items[ScriptConstants.HttpProxyingEnabled] = bool.TrueString;
9897

99-
// add invocation id as correlation id
100-
httpRequest.Headers.TryAdd(ScriptConstants.HttpProxyCorrelationHeader, context.ExecutionContext.InvocationId.ToString());
98+
// add invocation id as correlation id, override existing header if present
99+
httpRequest.Headers[ScriptConstants.HttpProxyCorrelationHeader] = context.ExecutionContext.InvocationId.ToString();
101100

102101
var forwardingTask = _httpForwarder.SendAsync(httpContext, httpUri.ToString(), _messageInvoker, _forwarderRequestConfig).AsTask();
103102
context.Properties[ScriptConstants.HttpProxyTask] = forwardingTask;

src/WebJobs.Script.WebHost/Configuration/FlexConsumptionMetricsPublisherOptions.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ public class FlexConsumptionMetricsPublisherOptions
1414
internal const int DefaultMetricsPublishIntervalMS = 5000;
1515
internal const int DefaultMinimumActivityIntervalMS = 1000;
1616
internal const int DefaultMetricsGranularityMS = 100;
17+
internal const int DefaultKeepAliveIntervalMS = 30000;
1718

1819
public FlexConsumptionMetricsPublisherOptions()
1920
{
2021
MetricsPublishIntervalMS = DefaultMetricsPublishIntervalMS;
2122
MinimumActivityIntervalMS = DefaultMinimumActivityIntervalMS;
2223
MetricsGranularityMS = DefaultMetricsGranularityMS;
24+
KeepAliveIntervalMS = DefaultKeepAliveIntervalMS;
2325
InitialPublishDelayMS = Utility.ColdStartDelayMS;
2426

2527
// Default this to 15 minutes worth of files
@@ -66,5 +68,14 @@ public FlexConsumptionMetricsPublisherOptions()
6668
/// When over this limit, the oldest files will be deleted to make room for new files.
6769
/// </remarks>
6870
public int MaxFileCount { get; set; }
71+
72+
/// <summary>
73+
/// Gets or sets the maximum interval at which metrics are published.
74+
/// </summary>
75+
/// <remarks>
76+
/// This is required to ensure that we publish something even if there are no
77+
/// new metrics or activity to report so that we have a heartbeat.
78+
/// </remarks>
79+
public int KeepAliveIntervalMS { get; set; }
6980
}
7081
}

0 commit comments

Comments
 (0)