Bird
Raised Fist0
Azurecloud~20 mins

Durable Functions orchestration patterns in Azure - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Durable Functions Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
service_behavior
intermediate
2:00remaining
What happens when a Durable Function orchestration calls an activity function that fails?

Consider a Durable Function orchestration that calls an activity function which throws an exception. What is the default behavior of the orchestration?

AThe orchestration retries the activity function automatically based on the retry policy if configured; otherwise, it fails and stops.
BThe orchestration ignores the failure and continues executing the next activity functions.
CThe orchestration immediately restarts from the beginning without any retries.
DThe orchestration pauses indefinitely until manual intervention.
Attempts:
2 left
💡 Hint

Think about how Durable Functions handle errors and retries in activity functions.

Architecture
intermediate
2:00remaining
Which orchestration pattern is best for running multiple activity functions in parallel and waiting for all to complete?

You want to run several independent activity functions at the same time and proceed only after all have finished. Which Durable Functions orchestration pattern should you use?

AAsync HTTP APIs pattern
BFunction chaining pattern
CFan-out/fan-in pattern
DMonitor pattern
Attempts:
2 left
💡 Hint

Consider which pattern allows parallel execution and aggregation of results.

Configuration
advanced
2:00remaining
What is the correct way to implement a Durable Function that waits for an external event before continuing?

You want your orchestration to pause and wait until it receives a specific external event named 'ApprovalReceived'. Which code snippet correctly implements this behavior?

Azure
public static async Task RunOrchestrator([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    // Wait for external event
    var approval = await context.WaitForExternalEvent<bool>("ApprovalReceived");
    if (approval)
    {
        await context.CallActivityAsync("ProcessApproval", null);
    }
    else
    {
        await context.CallActivityAsync("RejectApproval", null);
    }
}
Aawait context.WaitForExternalEvent<bool>();
Bawait context.WaitForExternalEvent("ApprovalReceived");
Cawait context.WaitForExternalEvent<int>("ApprovalReceived");
Dawait context.WaitForExternalEvent<bool>("ApprovalReceived");
Attempts:
2 left
💡 Hint

Check the method signature and required parameters for waiting on external events.

security
advanced
2:00remaining
How can you securely pass sensitive data to an activity function in Durable Functions?

You need to send a secret API key to an activity function without exposing it in logs or storage. What is the best practice to handle this?

AStore the secret in Azure Key Vault and retrieve it inside the activity function at runtime.
BHardcode the secret inside the activity function code.
CInclude the secret in the orchestration input JSON to keep it encrypted automatically.
DPass the secret as a parameter directly from the orchestration function to the activity function.
Attempts:
2 left
💡 Hint

Think about secure storage and minimizing exposure of secrets.

🧠 Conceptual
expert
3:00remaining
What is the main advantage of Durable Functions' 'function chaining' pattern compared to traditional sequential function calls?

Durable Functions support a 'function chaining' pattern where one function calls another in sequence. What key benefit does this pattern provide over normal sequential calls in serverless environments?

AIt executes all functions in parallel to reduce total execution time.
BIt preserves state and checkpoints progress between function calls, allowing reliable long-running workflows.
CIt automatically scales the number of function instances based on CPU usage.
DIt encrypts all data passed between functions by default.
Attempts:
2 left
💡 Hint

Consider how Durable Functions manage state and reliability in workflows.

Practice

(1/5)
1. What is the main role of an orchestrator function in Azure Durable Functions?
easy
A. To perform the actual work like processing data
B. To coordinate and manage the workflow of multiple tasks
C. To store data permanently in the cloud
D. To send notifications to users

Solution

  1. Step 1: Understand the function types in Durable Functions

    Durable Functions use orchestrator functions to manage workflows and activity functions to perform tasks.
  2. Step 2: Identify the role of the orchestrator function

    The orchestrator function controls the order and timing of tasks but does not do the actual work itself.
  3. Final Answer:

    To coordinate and manage the workflow of multiple tasks -> Option B
  4. Quick Check:

    Orchestrator = workflow manager [OK]
Hint: Orchestrator controls flow; activity does the work [OK]
Common Mistakes:
  • Confusing orchestrator with activity function
  • Thinking orchestrator stores data
  • Assuming orchestrator sends notifications
2. Which of the following is the correct way to call an activity function named ProcessOrder from an orchestrator function in C#?
easy
A. await context.CallActivityAsync("ProcessOrder", orderId);
B. context.CallActivity("ProcessOrder", orderId);
C. await CallActivityAsync("ProcessOrder", orderId);
D. context.CallActivityAsync("ProcessOrder");

Solution

  1. Step 1: Recall the syntax for calling activity functions

    In Durable Functions, the orchestrator calls activities using await context.CallActivityAsync with the function name and input.
  2. Step 2: Check each option for correctness

    await context.CallActivityAsync("ProcessOrder", orderId); uses the correct method with await, context, function name, and input parameter.
  3. Final Answer:

    await context.CallActivityAsync("ProcessOrder", orderId); -> Option A
  4. Quick Check:

    Correct async call syntax = await context.CallActivityAsync("ProcessOrder", orderId); [OK]
Hint: Use await with context.CallActivityAsync and function name [OK]
Common Mistakes:
  • Omitting await keyword
  • Using wrong method name like CallActivity
  • Missing input parameter when required
3. Given this orchestrator code snippet in JavaScript:
const outputs = [];
outputs.push(await context.callActivity('TaskA', 1));
outputs.push(await context.callActivity('TaskB', 2));
return outputs;

What will the orchestrator return?
medium
A. An array with results from TaskA and TaskB in order
B. A single result from TaskB only
C. An empty array
D. A promise object instead of results

Solution

  1. Step 1: Analyze the code execution flow

    The orchestrator calls TaskA and waits for its result, then calls TaskB and waits for its result, pushing both into the outputs array.
  2. Step 2: Understand the return value

    Since both calls are awaited, outputs will contain the results of TaskA and TaskB in order.
  3. Final Answer:

    An array with results from TaskA and TaskB in order -> Option A
  4. Quick Check:

    Awaited calls return results in array [OK]
Hint: Await each call to get results in order [OK]
Common Mistakes:
  • Assuming only last result is returned
  • Thinking outputs is empty without awaits
  • Confusing promise with resolved value
4. You wrote this orchestrator function in C#:
public async Task<string> RunOrchestrator(IDurableOrchestrationContext context)
{
    var result = context.CallActivityAsync<string>("DoWork", null);
    return result.Result;
}

What is the problem with this code?
medium
A. It calls the wrong method for activity
B. It correctly returns the activity result
C. It misses the await keyword causing a compile error
D. It blocks the orchestrator causing a deadlock

Solution

  1. Step 1: Identify async call usage

    The code calls CallActivityAsync but does not await it, instead accesses result.Result synchronously.
  2. Step 2: Understand deadlock risk in orchestrators

    Accessing Result blocks the thread and can cause deadlocks in async orchestrator functions.
  3. Final Answer:

    It blocks the orchestrator causing a deadlock -> Option D
  4. Quick Check:

    Use await, not .Result, to avoid deadlocks [OK]
Hint: Always await async calls in orchestrators [OK]
Common Mistakes:
  • Using .Result instead of await
  • Ignoring async method patterns
  • Assuming synchronous access works fine
5. You want to run three activity functions Task1, Task2, and Task3 in parallel and wait for all to finish before continuing. Which orchestrator pattern correctly achieves this in JavaScript Durable Functions?
hard
A. await context.callActivity('Task1'); await context.callActivity('Task2'); await context.callActivity('Task3');
B. const results = []; results.push(await context.callActivity('Task1')); results.push(await context.callActivity('Task2')); results.push(await context.callActivity('Task3'));
C. const tasks = [ context.callActivity('Task1'), context.callActivity('Task2'), context.callActivity('Task3') ]; const results = await Promise.all(tasks);
D. const results = await context.callActivity('Task1') + await context.callActivity('Task2') + await context.callActivity('Task3');

Solution

  1. Step 1: Understand parallel execution in JavaScript

    To run tasks in parallel, start them without awaiting immediately, collect promises, then await all together.
  2. Step 2: Analyze each option

    const tasks = [ context.callActivity('Task1'), context.callActivity('Task2'), context.callActivity('Task3') ]; const results = await Promise.all(tasks); creates an array of promises and awaits them all with Promise.all, running tasks concurrently.
  3. Final Answer:

    Use Promise.all with array of activity calls for parallel execution -> Option C
  4. Quick Check:

    Parallel = start all, then await all [OK]
Hint: Use Promise.all to await multiple tasks in parallel [OK]
Common Mistakes:
  • Awaiting each task sequentially (Options A and C)
  • Trying to add awaited results (Option D)
  • Not collecting promises before awaiting