Question

Difficulty: MediumImplement Durable Functions

You are developing a telemetry processing workflow using Azure Durable Functions in Node.js. The orchestrator function must process incoming data, wait for 5 minutes, and then run an aggregation activity. You write the following orchestrator function code:

javascript
const df = require("durable-functions");

module.exports = df.orchestrator(function* (context) {
const input = context.df.getInput();

// Generate a unique identifier for the execution run
const runId = context.df.newGuid();

// Get the current date and time
const timestamp = new Date();

// Perform processing by calling an activity function
const processedData = yield context.df.callActivity("ProcessSensorData", input);

// Delay execution for 5 minutes
yield context.df.createTimer(new Date(Date.now() + 5 * 60 * 1000));

// Run the aggregation activity
yield context.df.callActivity("AggregateSensorData", { runId, timestamp, processedData });
});

During testing, you notice that the orchestrator behaves non-deterministically. Which two changes should you make to ensure the orchestrator complies with Durable Functions determinism constraints? Select two.

  1. Replace the instantiation of the local system date new Date() with context.df.currentUtcDateTime to capture the timestamp.Answer
  2. Calculate the timer deadline using context.df.currentUtcDateTime instead of Date.now().Answer
  3. C
    Replace context.df.newGuid() with the standard Node.js crypto.randomUUID() method to ensure unique tracking IDs.
  4. D
    Replace the activity calls with inline HTTP requests using a library like axios to execute the tasks directly within the orchestrator.

Answer

Replace the instantiation of the local system date new Date() with context.df.currentUtcDateTime to capture the timestamp, and calculate the timer deadline using context.df.currentUtcDateTime instead of Date.now().
To ensure the orchestrator function is deterministic, all date and time operations must use the API provided by the Durable Functions context (context.df.currentUtcDateTime). The native JavaScript new Date() and Date.now() are non-deterministic because they return different values on each execution replay, causing the execution history to mismatch. Replacing them with the context's currentUtcDateTime property ensures consistent values across replays. The context.df.newGuid() is already the correct deterministic API for generating unique identifiers, and activity calls are required for I/O operations.

Step-by-Step Solution

1
Analyze the orchestrator code for sources of non-determinism.
Identify that new Date() and Date.now() are used to fetch the current timestamp and to compute the timer's expiration time.
Orchestrator functions replay multiple times to rebuild their execution state, and native system date/time calls will return different values on each replay.
2
Replace the non-deterministic date/time retrievals with deterministic alternatives.
Replace new Date() and Date.now() with context.df.currentUtcDateTime.
The Durable Functions framework provides context.df.currentUtcDateTime to ensure that time values are recorded in the execution history and replayed consistently.
3
Verify that remaining APIs are compliant with Durable Functions constraints.
Keep context.df.newGuid() for UUID generation and use activity calls for operations rather than direct HTTP clients.
context.df.newGuid() is safe for orchestrators, and network or direct database operations must go through activity functions to maintain determinism.

Key Concept

Orchestrator code determinism constraints in Azure Durable Functions
Rate this question