Skip to content

Commit 21f26af

Browse files
Merge pull request #247065 from mattchenderson/coldstart
adding placeholder instructions
2 parents 835a37b + c25d214 commit 21f26af

File tree

2 files changed

+128
-6
lines changed

2 files changed

+128
-6
lines changed

articles/azure-functions/dotnet-isolated-in-process-differences.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ Use the following table to compare feature and functional differences between th
3030
| Model types exposed by bindings | Simple types<br/>[JSON serializable](/dotnet/api/system.text.json.jsonserializeroptions) types<br/>Arrays/enumerations<br/>Service SDK types<sup>4</sup> | Simple types<br/>JSON serializable types<br/>Arrays/enumerations<br/>[Service SDK types](dotnet-isolated-process-guide.md#sdk-types)<sup>4</sup> |
3131
| HTTP trigger model types| [HttpRequest] / [IActionResult]<sup>5</sup><br/>[HttpRequestMessage] / [HttpResponseMessage] | [HttpRequestData] / [HttpResponseData]<br/>[HttpRequest] / [IActionResult] (using [ASP.NET Core integration][aspnetcore-integration])<sup>5</sup>|
3232
| Output binding interactions | Return values (single output only),<br/>`out` parameters,<br/>`IAsyncCollector` | Return values in an expanded model with:<br/> - single or [multiple outputs](dotnet-isolated-process-guide.md#multiple-output-bindings)<br/> - arrays of outputs|
33-
| Imperative bindings<sup>1</sup> | [Supported](functions-dotnet-class-library.md#binding-at-runtime) | Not supported |
33+
| Imperative bindings<sup>1</sup> | [Supported](functions-dotnet-class-library.md#binding-at-runtime) | Not supported - instead [work with SDK types directly](./dotnet-isolated-process-guide.md#register-azure-clients) |
3434
| Dependency injection | [Supported](functions-dotnet-dependency-injection.md) | [Supported](dotnet-isolated-process-guide.md#dependency-injection) (improved model consistent with .NET ecosystem) |
3535
| Middleware | Not supported | [Supported](dotnet-isolated-process-guide.md#middleware) |
3636
| Logging | [ILogger] passed to the function<br/>[ILogger&lt;T&gt;] via [dependency injection](functions-dotnet-dependency-injection.md) | [ILogger&lt;T&gt;]/[ILogger] obtained from [FunctionContext](/dotnet/api/microsoft.azure.functions.worker.functioncontext) or via [dependency injection](dotnet-isolated-process-guide.md#dependency-injection)|
3737
| Application Insights dependencies | [Supported](functions-monitoring.md#dependencies) | [Supported](./dotnet-isolated-process-guide.md#application-insights) |
3838
| Cancellation tokens | [Supported](functions-dotnet-class-library.md#cancellation-tokens) | [Supported](dotnet-isolated-process-guide.md#cancellation-tokens) |
39-
| Cold start times<sup>2</sup> | (Baseline) | Additionally includes process launch |
39+
| Cold start times<sup>2</sup> | Optimized | [Configurable optimizations (preview)](./dotnet-isolated-process-guide.md#performance-optimizations) |
4040
| ReadyToRun | [Supported](functions-dotnet-class-library.md#readytorun) | [Supported](dotnet-isolated-process-guide.md#readytorun) |
4141

4242
<sup>1</sup> When you need to interact with a service using parameters determined at runtime, using the corresponding service SDKs directly is recommended over using imperative bindings. The SDKs are less verbose, cover more scenarios, and have advantages for error handling and debugging purposes. This recommendation applies to both models.

articles/azure-functions/dotnet-isolated-process-guide.md

Lines changed: 126 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,13 +219,127 @@ The following example performs clean-up actions if a cancellation request has be
219219

220220
:::code language="csharp" source="~/azure-functions-dotnet-worker/samples/Net7Worker/EventHubCancellationToken.cs" id="docsnippet_cancellation_token_cleanup":::
221221

222-
## ReadyToRun
222+
## Performance optimizations
223223

224-
You can compile your function app as [ReadyToRun binaries](/dotnet/core/deploying/ready-to-run). ReadyToRun is a form of ahead-of-time compilation that can improve startup performance to help reduce the effect of [cold-start](event-driven-scaling.md#cold-start) when running in a [Consumption plan](consumption-plan.md).
224+
This section outlines options you can enable to improve performance around [cold start](./event-driven-scaling.md#cold-start).
225225

226-
ReadyToRun is available in .NET 6 and later versions and requires [version 4.0 or later](functions-versions.md) of the Azure Functions runtime.
226+
### Placeholders (preview)
227227

228-
To compile your project as ReadyToRun, update your project file by adding the `<PublishReadyToRun>` and `<RuntimeIdentifier>` elements. The following is the configuration for publishing to a Windows 32-bit function app.
228+
Placeholders are a platform capability that improves cold start. Normally, you do not have to be aware of them, but during the preview period for placeholders for .NET Isolated, they require some opt-in configuration. Placeholders require .NET 6 or later. To enable placeholders:
229+
230+
- Set the `WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED` application setting to "1"
231+
- Ensure that the `netFrameworkVersion` property of the function app matches your project's target framework, which must be .NET 6 or later.
232+
- Update your project file:
233+
- Upgrade [Microsoft.Azure.Functions.Worker] to version 1.19.0 or later
234+
- Upgrade [Microsoft.Azure.Functions.Worker.Sdk] to version 1.14.1 or later
235+
- Add a framework reference to `Microsoft.AspNetCore.App`
236+
- Set the property `FunctionsEnableWorkerIndexing` to "True".
237+
- Set the property `FunctionsAutoRegisterGeneratedMetadataProvider` to "True"
238+
239+
> [!NOTE]
240+
> Setting `FunctionsEnableWorkerIndexing` to "True" may cause an issue when debugging locally using version 4.0.5274 or earlier of the [Azure Functions Core Tools](./functions-run-local.md). The issue manifests with the debugger not being able to attach. If you encounter this issue, remove the `FunctionsEnableWorkerIndexing` property during local testing.
241+
242+
The following CLI commands will set the application setting and update the `netFrameworkVersion` property. Replace `<groupName>` with the name of the resource group, and replace `<appName>` with the name of your function app. Replace `<framework>` with the appropriate version string, such as "v6.0" or "v7.0", according to your target .NET version.
243+
244+
```azurecli
245+
az functionapp config appsettings set -g <groupName> -n <appName> --settings 'WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED=1'
246+
az functionapp config set -g <groupName> -n <appName> --net-framework-version <framework>
247+
```
248+
249+
The following example shows a project file with the appropriate changes in place:
250+
251+
```xml
252+
<Project Sdk="Microsoft.NET.Sdk">
253+
<PropertyGroup>
254+
<TargetFramework>net6.0</TargetFramework>
255+
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
256+
<OutputType>Exe</OutputType>
257+
<ImplicitUsings>enable</ImplicitUsings>
258+
<Nullable>enable</Nullable>
259+
<FunctionsEnableWorkerIndexing>True</FunctionsEnableWorkerIndexing>
260+
<FunctionsAutoRegisterGeneratedMetadataProvider>True</FunctionsAutoRegisterGeneratedMetadataProvider>
261+
</PropertyGroup>
262+
<ItemGroup>
263+
<FrameworkReference Include="Microsoft.AspNetCore.App" />
264+
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.19.0" />
265+
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.14.1" />
266+
</ItemGroup>
267+
<ItemGroup>
268+
<None Update="host.json">
269+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
270+
</None>
271+
<None Update="local.settings.json">
272+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
273+
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
274+
</None>
275+
</ItemGroup>
276+
<ItemGroup>
277+
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
278+
</ItemGroup>
279+
</Project>
280+
```
281+
282+
### Optimized executor (preview)
283+
284+
The function executor is a component of the platform that causes invocations to run. By default, it makes use of reflection, but a newer version is available in preview which removes this performance overhead. Normally, you do not have to be aware of this component, but during the preview period of the new version, it requires some opt-in configuration.
285+
286+
To enable the optimized executor, you must update your project file:
287+
288+
- Upgrade [Microsoft.Azure.Functions.Worker] to version 1.19.0 or later
289+
- Upgrade [Microsoft.Azure.Functions.Worker.Sdk] to version 1.14.1 or later
290+
- Set the property `FunctionsEnableExecutorSourceGen` to "True"
291+
292+
The following example shows a project file with the appropriate changes in place:
293+
294+
```xml
295+
<Project Sdk="Microsoft.NET.Sdk">
296+
<PropertyGroup>
297+
<TargetFramework>net6.0</TargetFramework>
298+
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
299+
<OutputType>Exe</OutputType>
300+
<ImplicitUsings>enable</ImplicitUsings>
301+
<Nullable>enable</Nullable>
302+
<FunctionsEnableExecutorSourceGen>True</FunctionsEnableExecutorSourceGen>
303+
</PropertyGroup>
304+
<ItemGroup>
305+
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.19.0" />
306+
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.14.1" />
307+
</ItemGroup>
308+
<ItemGroup>
309+
<None Update="host.json">
310+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
311+
</None>
312+
<None Update="local.settings.json">
313+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
314+
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
315+
</None>
316+
</ItemGroup>
317+
<ItemGroup>
318+
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
319+
</ItemGroup>
320+
</Project>
321+
```
322+
323+
### ReadyToRun
324+
325+
You can compile your function app as [ReadyToRun binaries](/dotnet/core/deploying/ready-to-run). ReadyToRun is a form of ahead-of-time compilation that can improve startup performance to help reduce the effect of cold starts when running in a [Consumption plan](consumption-plan.md). ReadyToRun is available in .NET 6 and later versions and requires [version 4.0 or later](functions-versions.md) of the Azure Functions runtime.
326+
327+
ReadyToRun requires you to build the project against the runtime architecture of the hosting app. **If these are not aligned, your app will encounter an error at startup.** Select your runtime identifier from the table below:
328+
329+
|Operating System | App is 32-bit | Runtime identifier |
330+
|-|-|-|
331+
| Windows | True | `win-x86` |
332+
| Windows | False | `win-x64` |
333+
| Linux | True | N/A (not supported) |
334+
| Linux | False | `linux-x64` |
335+
336+
To check if your Windows app is 32-bit or 64-bit, you can run the following CLI command, substituting `<group_name>` with the name of your resource group and `<app_name>` with the name of your application. An output of "true" indicates that the app is 32-bit, and "false" indicates 64-bit.
337+
338+
```azurecli
339+
az functionapp config show -g <group_name> -n <app_name> --query "use32BitWorkerProcess"
340+
```
341+
342+
To compile your project as ReadyToRun, update your project file by adding the `<PublishReadyToRun>` and `<RuntimeIdentifier>` elements. The following examples shows a configuration for publishing to a Windows 32-bit function app.
229343

230344
```xml
231345
<PropertyGroup>
@@ -236,6 +350,14 @@ To compile your project as ReadyToRun, update your project file by adding the `<
236350
</PropertyGroup>
237351
```
238352

353+
If you don't want to set the `<RuntimeIdentifier>` as part of the project file, you can also configure this as part of the publish gesture itself. For example, with a Windows 32-bit function app, the .NET CLI command would be:
354+
355+
```dotnetcli
356+
dotnet publish --runtime win-x86
357+
```
358+
359+
In Visual Studio, the "Target Runtime" option in the publish profile should be set to the correct runtime identifier. If it is set to the default value "Portable", ReadyToRun will not be used.
360+
239361
## Execution context
240362

241363
.NET isolated passes a [FunctionContext] object to your function methods. This object lets you get an [`ILogger`][ILogger] instance to write to the logs by calling the [GetLogger] method and supplying a `categoryName` string. To learn more, see [Logging](#logging).

0 commit comments

Comments
 (0)