2

I would like to have a service that is capable of starting an orchestration. I am using isolated model. Is it possible to inject DurableTaskClient through dependency injection?

I tried configuring service below and while DurableTaskClient gets injected it throws an exception. I suspect GRPC needs to be additionally configured somehow, maybe to point to task hub or something like that.

Any advice?

`

using DurableFuncExperiment;
using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
        services.AddTransient<DurableTaskService, DurableTaskService>();
        services.AddDurableTaskClient((builder) =>
        {
            builder.UseGrpc();
        });
    })
    .Build();

host.Run();


using Microsoft.DurableTask.Client;

namespace DurableFuncExperiment;
public class DurableTaskService(DurableTaskClient durableTaskClient)
{
    public async Task Execute()
    {
        string instanceId = await durableTaskClient.ScheduleNewOrchestrationInstanceAsync(Function.SayHelloEventOrchestrator);
    }
}`

Executed 'Functions.Jobs_SayHelloEventOrchestrator' (Failed, Id=9bc3cec2-749e-4a4a-9f6a-1b821839d6d4, Duration=6741ms) [2024-10-11T03:24:15.460Z] System.Private.CoreLib: Exception while executing function: Functions.Jobs_SayHelloEventOrchestrator. System.Private.CoreLib: Result: Failure Exception: System.MissingMethodException: Method not found: 'System.String Microsoft.DurableTask.Protobuf.ExecutionStartedEvent.get_CorrelationData()'. [2024-10-11T03:24:15.467Z] at Microsoft.DurableTask.ProtoUtils.ConvertHistoryEvent(HistoryEvent proto) [2024-10-11T03:24:15.469Z] at System.Linq.Enumerable.SelectIListIterator2.MoveNext() [2024-10-11T03:24:15.475Z] at Microsoft.DurableTask.Worker.Grpc.GrpcOrchestrationRunner.LoadAndRun(String encodedOrchestratorRequest, ITaskOrchestrator implementation, IServiceProvider services) [2024-10-11T03:24:15.479Z] at Microsoft.Azure.Functions.Worker.Extensions.DurableTask.DurableTaskFunctionsMiddleware.RunOrchestrationAsync(FunctionContext context, BindingMetadata triggerBinding, FunctionExecutionDelegate next) in /_/src/Worker.Extensions.DurableTask/DurableTaskFunctionsMiddleware.cs:line 58 [2024-10-11T03:24:15.483Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 77 [2024-10-11T03:24:15.491Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request) in D:\a\_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 88 Stack: at Microsoft.DurableTask.ProtoUtils.ConvertHistoryEvent(HistoryEvent proto) [2024-10-11T03:24:15.494Z] at System.Linq.Enumerable.SelectIListIterator2.MoveNext() [2024-10-11T03:24:15.496Z] at Microsoft.DurableTask.Worker.Grpc.GrpcOrchestrationRunner.LoadAndRun(String encodedOrchestratorRequest, ITaskOrchestrator implementation, IServiceProvider services) [2024-10-11T03:24:15.498Z] at Microsoft.Azure.Functions.Worker.Extensions.DurableTask.DurableTaskFunctionsMiddleware.RunOrchestrationAsync(FunctionContext context, BindingMetadata triggerBinding, FunctionExecutionDelegate next) in //src/Worker.Extensions.DurableTask/DurableTaskFunctionsMiddleware.cs:line 58 [2024-10-11T03:24:15.501Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 77 [2024-10-11T03:24:15.511Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request) in D:\a_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 88. [2024-10-11T03:24:15.514Z] ede0fd849a0d409b9f0c4bee61e938fb: Function 'Jobs_SayHelloEventOrchestrator (Orchestrator)' failed with an error. Reason: Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.Jobs_SayHelloEventOrchestrator [2024-10-11T03:24:15.517Z] ---> Microsoft.Azure.WebJobs.Script.Workers.Rpc.RpcException: Result: Failure Exception: System.MissingMethodException: Method not found: 'System.String Microsoft.DurableTask.Protobuf.ExecutionStartedEvent.get_CorrelationData()'. [2024-10-11T03:24:15.521Z] at Microsoft.DurableTask.ProtoUtils.ConvertHistoryEvent(HistoryEvent proto) [2024-10-11T03:24:15.523Z] at System.Linq.Enumerable.SelectIListIterator2.MoveNext() [2024-10-11T03:24:15.524Z] at Microsoft.DurableTask.Worker.Grpc.GrpcOrchestrationRunner.LoadAndRun(String encodedOrchestratorRequest, ITaskOrchestrator implementation, IServiceProvider services) [2024-10-11T03:24:15.526Z] at Microsoft.Azure.Functions.Worker.Extensions.DurableTask.DurableTaskFunctionsMiddleware.RunOrchestrationAsync(FunctionContext context, BindingMetadata triggerBinding, FunctionExecutionDelegate next) in /_/src/Worker.Extensions.DurableTask/DurableTaskFunctionsMiddleware.cs:line 58 [2024-10-11T03:24:15.528Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 77 [2024-10-11T03:24:15.530Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request) in D:\a\_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 88 Stack: at Microsoft.DurableTask.ProtoUtils.ConvertHistoryEvent(HistoryEvent proto) [2024-10-11T03:24:15.535Z] at System.Linq.Enumerable.SelectIListIterator2.MoveNext() [2024-10-11T03:24:15.537Z] at Microsoft.DurableTask.Worker.Grpc.GrpcOrchestrationRunner.LoadAndRun(String encodedOrchestratorRequest, ITaskOrchestrator implementation, IServiceProvider services) [2024-10-11T03:24:15.540Z] at Microsoft.Azure.Functions.Worker.Extensions.DurableTask.DurableTaskFunctionsMiddleware.RunOrchestrationAsync(FunctionContext context, BindingMetadata triggerBinding, FunctionExecutionDelegate next) in //src/Worker.Extensions.DurableTask/DurableTaskFunctionsMiddleware.cs:line 58 [2024-10-11T03:24:15.542Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 77 [2024-10-11T03:24:15.544Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request) in D:\a_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 88 [2024-10-11T03:24:15.546Z] at Microsoft.Azure.WebJobs.Script.Description.WorkerFunctionInvoker.InvokeCore(Object[] parameters, FunctionInvocationContext context) in //src/WebJobs.Script/Description/Workers/WorkerFunctionInvoker.cs:line 101 [2024-10-11T03:24:15.551Z] at Microsoft.Azure.WebJobs.Script.Description.FunctionInvokerBase.Invoke(Object[] parameters) in //src/WebJobs.Script/Description/FunctionInvokerBase.cs:line 82 [2024-10-11T03:24:15.553Z] at Microsoft.Azure.WebJobs.Script.Description.FunctionGenerator.Coerce[T](Task1 src) in /_/src/WebJobs.Script/Description/FunctionGenerator.cs:line 225 [2024-10-11T03:24:15.556Z] at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker2.InvokeAsync(Object instance, Object[] arguments) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 53 [2024-10-11T03:24:15.558Z] at Microsoft.Azure.WebJobs.Extensions.DurableTask.OutOfProcMiddleware.<>c__DisplayClass10_0.<b__0>d.MoveNext() in D:\a_work\1\s\src\WebJobs.Extensions.DurableTask\OutOfProcMiddleware.cs:line 130 [2024-10-11T03:24:15.560Z] --- End of stack trace from previous location --- [2024-10-11T03:24:15.561Z] at Microsoft.Azure.WebJobs.Host.Executors.TriggeredFunctionExecutor`1.<>c__DisplayClass7_0.<b__0>d.MoveNext() in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\TriggeredFunctionExecutor.cs:line 51 [2024-10-11T03:24:15.563Z] --- End of stack trace from previous location --- [2024-10-11T03:24:15.568Z] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeWithTimeoutAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean throwOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 581 [2024-10-11T03:24:15.572Z] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 527 [2024-10-11T03:24:15.574Z] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 306 [2024-10-11T03:24:15.576Z] --- End of inner exception stack trace --- [2024-10-11T03:24:15.578Z] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 352 [2024-10-11T03:24:15.583Z] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsync(IFunctionInstance functionInstance, CancellationToken cancellationToken) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 108. IsReplay: False. State: Failed. RuntimeStatus: Failed. HubName: TestHubName. AppName: . SlotName: . ExtensionVersion: 2.13.1. SequenceNumber: 11. TaskEventId: -1

1
  • Can you provide your complete function code like the code for SayHelloEventOrchestrator Commented Oct 11, 2024 at 6:46

1 Answer 1

0

You need to make sure that you are using correct packages and also verify your code. I am sharing my code here which I have used for testing purpose.

I have following 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>_79076732</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" Version="3.2.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.3.2" />
    <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 have created a separate file named DurableTaskService which has below given code.

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.DurableTask.Client;

namespace _79076732
{
    public class DurableTaskService
    {
        private readonly DurableTaskClient _durableTaskClient;

        public DurableTaskService(DurableTaskClient durableTaskClient)
        {
            _durableTaskClient = durableTaskClient;
        }

        public async Task<HttpResponseData> ExecuteAsync(HttpRequestData req)
        {
            string instanceId = await _durableTaskClient.ScheduleNewOrchestrationInstanceAsync("SayHelloEventOrchestrator");
            Console.WriteLine($"Started orchestration with ID = {instanceId}");
            var result = await _durableTaskClient.CreateCheckStatusResponseAsync(req, instanceId);

            return result;
        }
    }
}

Then I registered it in program.cs file.

using _79076732;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
        services.Configure<KestrelServerOptions>(options =>
        {
            options.AllowSynchronousIO = true;
        });
        services.AddTransient<DurableTaskService, DurableTaskService>();
        services.AddDurableTaskClient((builder) =>
        {
            builder.UseGrpc();
        });
    })
    .Build();

host.Run();

Lastly, I am invoking DurableTaskService using a http triggered function.

using Microsoft.DurableTask;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;

namespace _79076732
{
    public class Function1
    {
        private readonly DurableTaskService _durableTaskService;

        public Function1 (DurableTaskService durableTaskService)
        {
            _durableTaskService = durableTaskService;
        }

        [Function("SayHelloEventOrchestrator")]
        public async Task<string> SayHelloOrchestrator([OrchestrationTrigger] TaskOrchestrationContext context)
        {
            var result = await context.CallActivityAsync<string>("SayHello", "Afreen");
            return result;
        }

        [Function("SayHello")]
        public string SayHello([ActivityTrigger] string name)
        {
            return $"Hello, {name}!";
        }

        [Function("StartOrchestration")]
        public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req, FunctionContext executionContext)
        {
            var logger = executionContext.GetLogger("StartOrchestrationFunction");
            logger.LogInformation("Starting orchestration...");

            var orchestrationResult = await _durableTaskService.ExecuteAsync(req);

            return orchestrationResult;
        }
    }
}

By doing the above given steps, I am able to get the expected response.

Azure Functions Core Tools
Core Tools Version:       4.0.6280 Commit hash: N/A +421f0144b42047aa289ce691dc6db4fc8b6143e6 (64-bit)
Function Runtime Version: 4.834.3.22875

[2024-10-11T08:04:13.447Z] Found C:\Users\*****\79076732\79076732.csproj. Using for user secrets file configuration.
[2024-10-11T08:04:17.440Z] Azure Functions .NET Worker (PID: 19544) initialized in debug mode. Waiting for debugger to attach...
[2024-10-11T08:04:17.497Z] Worker process started and initialized.

Functions:

        StartOrchestration: [GET,POST] http://localhost:7230/api/StartOrchestration

        SayHello: activityTrigger

        SayHelloEventOrchestrator: orchestrationTrigger

For detailed output, run func with --verbose flag.
[2024-10-11T08:04:22.487Z] Host lock lease acquired by instance ID '0000000000000000000000000D2022A4'.
[2024-10-11T08:04:30.630Z] Executing 'Functions.StartOrchestration' (Reason='This function was programmatically called via the host APIs.', Id=70ee6cb7-000e-462d-b6b0-db15a0d812a2)
[2024-10-11T08:04:31.024Z] Scheduling new SayHelloEventOrchestrator orchestration with instance ID 'c626f9f4c2904356aa9fce247ac270ee' and 0 bytes of input data.
[2024-10-11T08:04:31.024Z] Starting orchestration...
[2024-10-11T08:04:31.226Z] Started orchestration with ID = c626f9f4c2904356aa9fce247ac270ee
[2024-10-11T08:04:31.301Z] Executed 'Functions.StartOrchestration' (Succeeded, Id=70ee6cb7-000e-462d-b6b0-db15a0d812a2, Duration=712ms)
[2024-10-11T08:04:31.320Z] Executing 'Functions.SayHelloEventOrchestrator' (Reason='(null)', Id=fc774ab1-d7fe-42e1-bc68-45c275bcd0f8)
[2024-10-11T08:04:31.508Z] Executed 'Functions.SayHelloEventOrchestrator' (Succeeded, Id=fc774ab1-d7fe-42e1-bc68-45c275bcd0f8, Duration=202ms)
[2024-10-11T08:04:31.567Z] Executing 'Functions.SayHello' (Reason='(null)', Id=f376e280-6741-4eda-9fe2-4d43f79ff1f9)
[2024-10-11T08:04:31.582Z] Executed 'Functions.SayHello' (Succeeded, Id=f376e280-6741-4eda-9fe2-4d43f79ff1f9, Duration=17ms)
[2024-10-11T08:04:31.651Z] Executing 'Functions.SayHelloEventOrchestrator' (Reason='(null)', Id=f52075b5-c10b-4f67-af85-bd933754b8ab)
[2024-10-11T08:04:31.685Z] Executed 'Functions.SayHelloEventOrchestrator' (Succeeded, Id=f52075b5-c10b-4f67-af85-bd933754b8ab, Duration=36ms)

enter image description here

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

In my project I added directly Microsoft.DurableTask.Client 1.3.0 and Microsoft.DurableTask.Client.Grpc. These packages seemed to be incompatible with what Worker assemblies are using (1.1.1 for both packages). Removing Microsoft.DurableTask.Client.xxx from project solved the problem. It's a minor version upgrade, but is still breaking tunction app. Thank you for taking time looking into this!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.