Skip to content

Commit 45271da

Browse files
committed
start the aca quickstart
Signed-off-by: Hannah Hunter <[email protected]>
1 parent 64a46a0 commit 45271da

File tree

4 files changed

+363
-0
lines changed

4 files changed

+363
-0
lines changed

articles/azure-functions/durable/TOC.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
- name: Configure Durable Functions app with Durable Task Scheduler
4242
displayName: get started, durable task scheduler
4343
href: ./durable-task-scheduler/quickstart-durable-task-scheduler.md
44+
- name: Configure a container app with Durable Task SDK and Durable Task Scheduler
45+
displayName: get started, durable task scheduler
46+
href: ./durable-task-scheduler/quickstart-aca-azd-durable-task-sdk.md
4447
- name: Configure Durable Functions app with MSSQL
4548
href: quickstart-mssql.md
4649
- name: Configure Durable Functions app with managed identity
Loading
Loading
Lines changed: 360 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
---
2+
title: "Quickstart: Set a portable Durable Task SDK in your application to use Azure Functions Durable Task Scheduler (preview)"
3+
description: Learn how to configure an existing container app for the Azure Functions Durable Task Scheduler using the portable Durable Task SDKs and deploy using Azure Developer CLI.
4+
ms.topic: how-to
5+
ms.date: 04/29/2025
6+
zone_pivot_groups: df-languages
7+
---
8+
9+
# Quickstart: Set a portable Durable Task SDK in your container app to use Azure Functions Durable Task Scheduler (preview)
10+
11+
::: zone pivot="javascript"
12+
13+
[!INCLUDE [preview-sample-limitations](./includes/preview-sample-limitations.md)]
14+
15+
::: zone-end
16+
17+
::: zone pivot="powershell"
18+
19+
[!INCLUDE [preview-sample-limitations](./includes/preview-sample-limitations.md)]
20+
21+
::: zone-end
22+
23+
::: zone pivot="csharp,python,java"
24+
25+
In this quickstart, you learn how to:
26+
27+
> [!div class="checklist"]
28+
>
29+
> - Set up and run the Durable Task Scheduler emulator for local development.
30+
> - Run the worker and client projects.
31+
> - Check the Azure Container Apps logs.
32+
> - Review orchestration status and history via the Durable Task Scheduler dashboard.
33+
34+
## Prerequisites
35+
36+
Before you begin:
37+
38+
::: zone-end
39+
40+
::: zone pivot="csharp"
41+
42+
- Make sure you have [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) or later.
43+
- Install [Docker](https://www.docker.com/products/docker-desktop/) for running the emulator.
44+
- Install [Azure Developer CLI](/azure/developer/azure-developer-cli/install-azd)
45+
- Clone the [Durable Task Scheduler GitHub repository](https://github.com/Azure-Samples/Durable-Task-Scheduler) to use the quickstart sample.
46+
47+
::: zone-end
48+
49+
50+
::: zone pivot="python"
51+
52+
- Make sure you have [Python 3.9+](https://www.python.org/downloads/) or later.
53+
- Install [Docker](https://www.docker.com/products/docker-desktop/) for running the emulator.
54+
- Install [Azure Developer CLI](/azure/developer/azure-developer-cli/install-azd)
55+
- Clone the [Durable Task Scheduler GitHub repository](https://github.com/Azure-Samples/Durable-Task-Scheduler) to use the quickstart sample.
56+
57+
::: zone-end
58+
59+
::: zone pivot="java"
60+
61+
- Make sure you have [Java 8 or 11](https://www.java.com/en/download/).
62+
- Install [Docker](https://www.docker.com/products/docker-desktop/) for running the emulator.
63+
- Install [Azure Developer CLI](/azure/developer/azure-developer-cli/install-azd)
64+
- Clone the [Durable Task Scheduler GitHub repository](https://github.com/Azure-Samples/Durable-Task-Scheduler) to use the quickstart sample.
65+
66+
::: zone-end
67+
68+
::: zone pivot="csharp,python,java"
69+
70+
## Prepare the project
71+
72+
::: zone-end
73+
74+
In a new terminal window, from the `Azure-Samples/Durable-Task-Scheduler` directory, navigate into the sample directory.
75+
76+
::: zone pivot="csharp"
77+
78+
```bash
79+
cd /samples/portable-sdks/dotnet/FunctionChaining
80+
```
81+
82+
::: zone-end
83+
84+
::: zone pivot="python"
85+
86+
```bash
87+
cd /samples/portable-sdks/python/FunctionChaining
88+
```
89+
90+
::: zone-end
91+
92+
::: zone pivot="java"
93+
94+
```bash
95+
cd /samples/portable-sdks/java/FunctionChaining
96+
```
97+
98+
::: zone-end
99+
100+
::: zone pivot="csharp,python,java"
101+
102+
## Deploy using Azure Developer CLI
103+
104+
1. Run `azd up` to provision the infrastructure and deploy the application to Azure Container Apps in a single command.
105+
106+
```azdeveloper
107+
azd up
108+
```
109+
110+
1. When prompted in the terminal, provide the following parameters.
111+
112+
| Parameter | Description |
113+
| --------- | ----------- |
114+
| Environment Name | Prefix for the resource group created to hold all Azure resources. |
115+
| Azure Location | The Azure location for your resources. |
116+
| Azure Subscription | The Azure subscription for your resources. |
117+
118+
This process may take some time to complete. As the `azd up` command completes, the CLI output displays two Azure portal links to monitor the deployment progress. The output also demonstrates how `azd up`:
119+
120+
- Creates and configures all necessary Azure resources via the provided Bicep files in the `./infra` directory using `azd provision`. Once provisioned by Azure Developer CLI, you can access these resources via the Azure portal. The files that provision the Azure resources include:
121+
- `main.parameters.json`
122+
- `main.bicep`
123+
- An `app` resources directory organized by functionality
124+
- A `core` reference library that contains the Bicep modules used by the `azd` template
125+
- Deploys the code using `azd deploy`
126+
127+
### Expected output
128+
129+
```azdeveloper
130+
Packaging services (azd package)
131+
132+
(✓) Done: Packaging service client
133+
- Image Hash: {IMAGE_HASH}
134+
- Target Image: {TARGET_IMAGE}
135+
136+
137+
(✓) Done: Packaging service worker
138+
- Image Hash: {IMAGE_HASH}
139+
- Target Image: {TARGET_IMAGE}
140+
141+
142+
Provisioning Azure resources (azd provision)
143+
Provisioning Azure resources can take some time.
144+
145+
Subscription: SUBSCRIPTION_NAME (SUBSCRIPTION_ID)
146+
Location: West US 2
147+
148+
You can view detailed progress in the Azure Portal:
149+
https://portal.azure.com/#view/HubsExtension/DeploymentDetailsBlade/~/overview/id/%2Fsubscriptions%SUBSCRIPTION_ID%2Fproviders%2FMicrosoft.Resources%2Fdeployments%2FCONTAINER_APP_ENVIRONMENT
150+
151+
(✓) Done: Resource group: GENERATED_RESOURCE_GROUP (1.385s)
152+
(✓) Done: Container Apps Environment: GENERATED_CONTAINER_APP_ENVIRONMENT (54.125s)
153+
(✓) Done: Container Registry: GENERATED_REGISTRY (1m27.747s)
154+
(✓) Done: Container App: SAMPLE_CLIENT_APP (21.39s)
155+
(✓) Done: Container App: SAMPLE_WORKER_APP (24.136s)
156+
157+
Deploying services (azd deploy)
158+
159+
(✓) Done: Deploying service client
160+
- Endpoint: https://SAMPLE_CLIENT_APP.westus2.azurecontainerapps.io/
161+
162+
(✓) Done: Deploying service worker
163+
- Endpoint: https://SAMPLE_WORKER_APP.westus2.azurecontainerapps.io/
164+
165+
166+
SUCCESS: Your up workflow to provision and deploy to Azure completed in 10 minutes 34 seconds. ```
167+
168+
## Confirm successful deployment
169+
170+
In the Azure portal, verify the client container app is publishing messages to the Azure Service Bus topic.
171+
172+
1. Copy the resource group name from the terminal output.
173+
174+
1. Sign in to the [Azure portal](https://portal.azure.com) and search for that resource group name.
175+
176+
1. From the resource group overview page, click on the client container app resource.
177+
178+
1. Select **Monitoring** > **Log stream**.
179+
180+
1. Confirm the client container is logging the function chaining tasks.
181+
182+
:::image type="content" source="media/quickstart-aca-azd-durable-task-sdk/client-app-log-stream.png" alt-text="Screenshot of the client container's log stream in the Azure portal.":::
183+
184+
1. Navigate back to the resource group page to select the `worker` container.
185+
186+
1. Select **Monitoring** > **Log stream**.
187+
188+
1. Confirm the client container is logging the function chaining tasks.
189+
190+
:::image type="content" source="media/quickstart-aca-azd-durable-task-sdk/worker-app-log-stream.png" alt-text="Screenshot of the worker container's log stream in the Azure portal.":::
191+
192+
::: zone-end
193+
194+
::: zone pivot="csharp,python,java"
195+
196+
## Understanding the code
197+
198+
::: zone-end
199+
200+
::: zone pivot="csharp"
201+
202+
### Worker Project
203+
204+
The Worker project contains:
205+
206+
- **GreetingOrchestration.cs**: Defines the orchestrator and activity functions in a single file
207+
- **Program.cs**: Sets up the worker host with proper connection string handling
208+
209+
#### Orchestration Implementation
210+
211+
The orchestration directly calls each activity in sequence using the standard `CallActivityAsync` method:
212+
213+
```csharp
214+
public override async Task<string> RunAsync(TaskOrchestrationContext context, string name)
215+
{
216+
// Step 1: Say hello to the person
217+
string greeting = await context.CallActivityAsync<string>(nameof(SayHelloActivity), name);
218+
219+
// Step 2: Process the greeting
220+
string processedGreeting = await context.CallActivityAsync<string>(nameof(ProcessGreetingActivity), greeting);
221+
222+
// Step 3: Finalize the response
223+
string finalResponse = await context.CallActivityAsync<string>(nameof(FinalizeResponseActivity), processedGreeting);
224+
225+
return finalResponse;
226+
}
227+
```
228+
229+
Each activity is implemented as a separate class decorated with the `[DurableTask]` attribute:
230+
231+
```csharp
232+
[DurableTask]
233+
public class SayHelloActivity : TaskActivity<string, string>
234+
{
235+
// Implementation details
236+
}
237+
```
238+
239+
The worker uses Microsoft.Extensions.Hosting for proper lifecycle management:
240+
```csharp
241+
var builder = Host.CreateApplicationBuilder();
242+
builder.Services.AddDurableTaskWorker()
243+
.AddTasks(registry => {
244+
registry.AddAllGeneratedTasks();
245+
})
246+
.UseDurableTaskScheduler(connectionString);
247+
var host = builder.Build();
248+
await host.StartAsync();
249+
```
250+
251+
### Client Project
252+
253+
The Client project:
254+
255+
- Uses the same connection string logic as the worker
256+
- Schedules an orchestration instance with a name input
257+
- Waits for the orchestration to complete and displays the result
258+
- Uses WaitForInstanceCompletionAsync for efficient polling
259+
260+
```csharp
261+
var instance = await client.WaitForInstanceCompletionAsync(
262+
instanceId,
263+
getInputsAndOutputs: true,
264+
cts.Token);
265+
```
266+
267+
::: zone-end
268+
269+
::: zone pivot="python"
270+
271+
### Worker Project
272+
273+
The Worker project contains:
274+
275+
- ****: Defines the orchestrator and activity functions in a single file
276+
- ****: Sets up the worker host with proper connection string handling
277+
278+
#### Orchestration Implementation
279+
280+
The orchestration directly calls each activity in sequence using the standard `CallActivityAsync` method:
281+
282+
```python
283+
284+
```
285+
286+
Each activity is implemented as a separate class decorated with the `[DurableTask]` attribute:
287+
288+
```python
289+
290+
```
291+
292+
The worker uses Microsoft.Extensions.Hosting for proper lifecycle management:
293+
294+
```python
295+
296+
```
297+
298+
### Client Project
299+
300+
The Client project:
301+
302+
- Uses the same connection string logic as the worker
303+
- Schedules an orchestration instance with a name input
304+
- Waits for the orchestration to complete and displays the result
305+
- Uses WaitForInstanceCompletionAsync for efficient polling
306+
307+
```python
308+
309+
```
310+
311+
312+
::: zone-end
313+
314+
::: zone pivot="java"
315+
316+
### Worker Project
317+
318+
The Worker project contains:
319+
320+
- ****: Defines the orchestrator and activity functions in a single file
321+
- ****: Sets up the worker host with proper connection string handling
322+
323+
#### Orchestration Implementation
324+
325+
The orchestration directly calls each activity in sequence using the standard `CallActivityAsync` method:
326+
327+
```java
328+
329+
```
330+
331+
Each activity is implemented as a separate class decorated with the `[DurableTask]` attribute:
332+
333+
```java
334+
335+
```
336+
337+
The worker uses Microsoft.Extensions.Hosting for proper lifecycle management:
338+
339+
```java
340+
341+
```
342+
343+
### Client Project
344+
345+
The Client project:
346+
347+
- Uses the same connection string logic as the worker
348+
- Schedules an orchestration instance with a name input
349+
- Waits for the orchestration to complete and displays the result
350+
- Uses WaitForInstanceCompletionAsync for efficient polling
351+
352+
```java
353+
354+
```
355+
356+
::: zone-end
357+
358+
## Next steps
359+
360+
Need

0 commit comments

Comments
 (0)