azure-functionsazure-durable-functions

Timer triggered Azure Durable function | orchestrationContext is null


I am trying to have an Azure Durable Function with Fan-out/Fan-in in C#.

For my orchestrator, I have the following signature.

  public static async Task TimerStart([TimerTrigger("0 */15 * * * *", RunOnStartup = true)] TimerInfo myTimer, [Microsoft.Azure.Functions.Worker.DurableClient] DurableTaskClient client, IDurableOrchestrationContext orchestrationContext)

The problem is how to call the Activity function. I am getting orchestrationContext as null.

Edit 1:

After input from Ikhtesam Afrin, I updated the code to the following:

public static async Task TimerStart([TimerTrigger("0 */15 * * * *", RunOnStartup = true)] TimerInfo myTimer, [DurableClient] DurableTaskClient client, TaskOrchestrationContext executionContext)

Still the variable executionContext is null. I have checked the references in csproj. They are in order.

It is an isolated function.


Solution

  • IDurableOrchestrationContext is being used for in-process function but it looks like you have created isolated durable function as you are using Microsoft.Azure.Functions.Worker.DurableClient package in your code. For isolated function, you need to use TaskOrchestrationContext.

    I have created the below durable function which worked as expected.

    using Microsoft.Azure.Functions.Worker;
    using Microsoft.DurableTask;
    using Microsoft.DurableTask.Client;
    using Microsoft.Extensions.Logging;
    
    namespace _79098074
    {
        public static class OrchestrationFunction
        {
            [Function(nameof(OrchestrationFunction))]
            public static async Task<List<string>> RunOrchestrator(
                [OrchestrationTrigger] TaskOrchestrationContext context)
            {
                ILogger logger = context.CreateReplaySafeLogger(nameof(OrchestrationFunction));
                logger.LogInformation("Saying hello.");
                var outputs = new List<string>();
    
                outputs.Add(await context.CallActivityAsync<string>(nameof(SayHello), "Tokyo"));
                outputs.Add(await context.CallActivityAsync<string>(nameof(SayHello), "Seattle"));
                outputs.Add(await context.CallActivityAsync<string>(nameof(SayHello), "London"));
    
                return outputs;
            }
    
            [Function(nameof(SayHello))]
            public static string SayHello([ActivityTrigger] string name, FunctionContext executionContext)
            {
                ILogger logger = executionContext.GetLogger("SayHello");
                logger.LogInformation("Saying hello to {name}.", name);
                return $"Hello {name}!";
            }
    
            [Function("Function1_TimerStart")]
            public static async Task TimerStart(
                [TimerTrigger("0 */5 * * * *")] TimerInfo timer,
                [DurableClient] DurableTaskClient client,
                FunctionContext executionContext)
            {
                ILogger logger = executionContext.GetLogger("Function1_TimerStart");
    
                string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
                    nameof(OrchestrationFunction));
    
                logger.LogInformation("Started orchestration with ID = '{instanceId}' via TimerTrigger.", instanceId);
            }
        }
    }
    

    You need to have correct packages in .csproj file.

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <AzureFunctionsVersion>v4</AzureFunctionsVersion>
        <OutputType>Exe</OutputType>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <RootNamespace>_79098074</RootNamespace>
      </PropertyGroup>
      <ItemGroup>
        <FrameworkReference Include="Microsoft.AspNetCore.App" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.23.0" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.1.7" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.3.2" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Timer" Version="4.3.1" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.18.1" />
        <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.4.0" />
      </ItemGroup>
      <ItemGroup>
        <None Update="host.json">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
        <None Update="local.settings.json">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
          <CopyToPublishDirectory>Never</CopyToPublishDirectory>
        </None>
      </ItemGroup>
      <ItemGroup>
        <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
      </ItemGroup>
    </Project>
    

    I am getting expected response.

    Azure Functions Core Tools
    Core Tools Version:       4.0.6517 Commit hash: N/A +6ee985b96787d19ddb1e56c5405f73fd3be9a32e (64-bit)
    Function Runtime Version: 4.1036.1.23224
    
    [2024-10-17T13:53:42.658Z] Found C:\Users\*******\79098074.csproj. Using for user secrets file configuration.
    [2024-10-17T13:53:47.675Z] Azure Functions .NET Worker (PID: 26456) initialized in debug mode. Waiting for debugger to attach...
    [2024-10-17T13:53:47.736Z] Worker process started and initialized.
    
    Functions:
    
            Function1_TimerStart: timerTrigger
    
            OrchestrationFunction: orchestrationTrigger
    
            SayHello: activityTrigger
    
    For detailed output, run func with --verbose flag.
    [2024-10-17T13:53:52.740Z] Host lock lease acquired by instance ID '0000000000000000000000000D2022A4'.
    [2024-10-17T13:55:00.086Z] Executing 'Functions.Function1_TimerStart' (Reason='Timer fired at 2024-10-17T19:25:00.0406031+05:30', Id=32f10855-20df-4275-9120-9f611386fa3b)
    [2024-10-17T13:55:00.472Z] Scheduling new OrchestrationFunction orchestration with instance ID '2e217858ec5043d6ac2ba51546aab827' and 0 bytes of input data.
    [2024-10-17T13:55:00.791Z] Started orchestration with ID = '2e217858ec5043d6ac2ba51546aab827' via TimerTrigger.
    [2024-10-17T13:55:00.841Z] Executed 'Functions.Function1_TimerStart' (Succeeded, Id=32f10855-20df-4275-9120-9f611386fa3b, Duration=789ms)
    [2024-10-17T13:55:00.922Z] Executing 'Functions.OrchestrationFunction' (Reason='(null)', Id=fb02e535-f75c-4f14-a913-69eec630371e)
    [2024-10-17T13:55:01.196Z] Saying hello.
    [2024-10-17T13:55:01.292Z] Executed 'Functions.OrchestrationFunction' (Succeeded, Id=fb02e535-f75c-4f14-a913-69eec630371e, Duration=402ms)
    [2024-10-17T13:55:01.421Z] Executing 'Functions.SayHello' (Reason='(null)', Id=f73fd98e-fe41-4135-bc5f-28d6d92dd34c)
    [2024-10-17T13:55:01.440Z] Saying hello to Tokyo.
    [2024-10-17T13:55:01.458Z] Executed 'Functions.SayHello' (Succeeded, Id=f73fd98e-fe41-4135-bc5f-28d6d92dd34c, Duration=42ms)
    [2024-10-17T13:55:01.556Z] Executing 'Functions.OrchestrationFunction' (Reason='(null)', Id=a94a6f54-17bf-4be0-bf47-2964e39d0d22)
    [2024-10-17T13:55:01.597Z] Executed 'Functions.OrchestrationFunction' (Succeeded, Id=a94a6f54-17bf-4be0-bf47-2964e39d0d22, Duration=46ms)
    [2024-10-17T13:55:01.653Z] Executing 'Functions.SayHello' (Reason='(null)', Id=4ddaee59-10b6-42e0-a2c8-ae3d6d0c6d13)
    [2024-10-17T13:55:01.666Z] Saying hello to Seattle.
    [2024-10-17T13:55:01.676Z] Executed 'Functions.SayHello' (Succeeded, Id=4ddaee59-10b6-42e0-a2c8-ae3d6d0c6d13, Duration=22ms)
    [2024-10-17T13:55:01.739Z] Executing 'Functions.OrchestrationFunction' (Reason='(null)', Id=a9f3c77e-cedd-4eb8-8ded-a2b297b2d086)
    [2024-10-17T13:55:01.771Z] Executed 'Functions.OrchestrationFunction' (Succeeded, Id=a9f3c77e-cedd-4eb8-8ded-a2b297b2d086, Duration=31ms)
    [2024-10-17T13:55:01.827Z] Executing 'Functions.SayHello' (Reason='(null)', Id=9a67f798-a7f2-4012-ba0f-48947ff656ff)
    [2024-10-17T13:55:01.839Z] Saying hello to London.
    [2024-10-17T13:55:01.851Z] Executed 'Functions.SayHello' (Succeeded, Id=9a67f798-a7f2-4012-ba0f-48947ff656ff, Duration=24ms)
    [2024-10-17T13:55:01.910Z] Executing 'Functions.OrchestrationFunction' (Reason='(null)', Id=a5452599-a604-4ca1-9fee-36365d9682bd)
    [2024-10-17T13:55:01.948Z] Executed 'Functions.OrchestrationFunction' (Succeeded, Id=a5452599-a604-4ca1-9fee-36365d9682bd, Duration=37ms)