Soru

Zorluk: ZorImplement Durable Functions

An organization has a workflow that polls the status of a long-running data export job. The workflow is implemented using Python Azure Durable Functions.

The orchestrator function is defined as follows:

python
import azure.functions as func
import azure.durable_functions as df
import datetime
import time

my_app = df.DFApp(http_auth_level=func.AuthLevel.ANONYMOUS)

@my_app.orchestration_trigger(context_name="context")
def export_monitor_orchestrator(context: df.DurableOrchestrationContext):
job_id = context.get_input()
expiry_time = datetime.datetime.utcnow() + datetime.timedelta(hours=2)

while datetime.datetime.utcnow() < expiry_time:
status = yield context.call_activity("CheckJobStatus", job_id)
if status == "Completed":
yield context.call_activity("SendSuccessAlert", job_id)
return "Finished"

time.sleep(300)

yield context.call_activity("SendTimeoutAlert", job_id)
return "Timeout"

The function app is hosted on an Azure Functions Consumption plan. During testing, the orchestration fails to complete successfully and frequently times out.

Which two modifications should you make to resolve the issues and ensure the orchestrator runs reliably? (Select two.)

  1. Replace the datetime.datetime.utcnow() calls with context.current_utc_datetime.Cevap
  2. Replace time.sleep(300) with a durable timer using yield context.create_timer().Cevap
  3. C
    Change the hosting plan of the Function App to a Premium or Dedicated (App Service) plan.
  4. D
    Call the status endpoint directly using a Python HTTP client library inside the orchestrator loop.

Cevap

Replace the datetime.datetime.utcnow() calls with context.current_utc_datetime and replace time.sleep(300) with a durable timer using yield context.create_timer().
To resolve the issues, the orchestrator must adhere to the determinism and non-blocking constraints of Azure Durable Functions. First, replacing the system clock calls with the context's current UTC datetime property ensures that the time remains consistent when the orchestrator replays. Second, replacing the thread-blocking sleep call with a durable timer yields control back to the functions host, allowing the orchestrator to shut down and wake up only when the timer expires. This avoids resource waste and runtime timeouts on the Consumption plan.

Adım Adım Çözüm

1
Identify the determinism violation in the orchestrator code.
The code calls datetime.datetime.utcnow() multiple times, which returns the current wall-clock time and changes value during orchestrator replays.
Orchestrator functions must be deterministic; using standard system clock methods causes a runtime discrepancy on replay, throwing a NonDeterministicOrchestrationException.
2
Identify the thread-blocking call in the orchestrator code.
The code uses time.sleep(300) to delay the execution loop.
Blocking the execution thread stops the orchestrator from yielding control back to the host, resulting in execution timeouts on the Consumption plan and unnecessary resource usage.
3
Refactor the non-deterministic time checks.
Replace datetime.datetime.utcnow() with context.current_utc_datetime.
The context property guarantees consistent datetime values across orchestrator replays.
4
Refactor the thread-blocking sleep call.
Replace time.sleep(300) with yield context.create_timer(context.current_utc_datetime + datetime.timedelta(seconds=300)).
This creates a durable, non-blocking timer that schedules a wake-up event in the task hub and safely stops the function instance, releasing CPU and memory resources.

Anahtar Kavram

Orchestrator function determinism and non-blocking execution constraints in Azure Durable Functions.
Bu soruyu puanla