Why are my Durable Entities not functioning after migrating from .NET 6 in-process to .NET 8 Isolated Worker?

Tony 0 Reputation points
2024-09-25T15:05:04.06+00:00

I am migrating from .NET6 in process model to .NET8 isolated worker model and having some issues with durable entities, mainly with passing input to the entity trigger. Every time the durable entity is called, the input parameter is now null after the migration changes. When doing a similar thing for an activity trigger, it works completely fine. I have yet to find an example that illustrates what I am trying to do so now I am questioning if I am doing something wrong. Below are some very basic examples before and after the switch from .NET6 in process to .NET8 isolated worker.

//.NET6 in-process orchestrator

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Extensions.Logging;

public class TestOrchestration
{
    [Timeout("01:00:00")]
    [FunctionName("TestOrchestration")]
    public async Task OrchestrateTest([OrchestrationTrigger] IDurableOrchestrationContext context)
    {
        var testRequest = context.GetInput<Event<TestRequest>>();

        var activityTriggerResponseId = await context.CallActivityAsync<string>("TestActivityTrigger", testRequest.Event.AccountId);

        var testEntity = new EntityId("TestEntityTrigger", context.NewGuid().ToString());
        var entityTriggerResponseId = await context.CallEntityAsync<string>(testEntity, "TestEntityTrigger", testRequest.Event.AccountId);
    }
}


//.NET6 in process entity trigger 

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Extensions.Logging;

public class TestEntityTrigger
{
    [Function("TestEntityTrigger")]
    public async Task TestTrigger([EntityTrigger] IDurableEntityContext context)
    {
        var input = context.GetInput<string>(); // input is read without issue

        return input;
    }
}


//.NET8 Isolated Worker orchestrator

using System;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;
using Microsoft.DurableTask.Entities;
using Microsoft.Extensions.Logging;

public class TestOrchestration
{
    [Function("TestOrchestration")]
    public async Task OrchestrateTest([OrchestrationTrigger] TaskOrchestrationContext context, Event<TestRequest> testRequest)
    {
        var activityTriggerResponseId = await context.CallActivityAsync<string>("TestActivityTrigger", testRequest.Event.AccountId);

        var testEntity = new EntityId("TestEntityTrigger", context.NewGuid().ToString());
        var entityTriggerResponseId = await context.Entities.CallEntityAsync<string>(testEntity, "TestEntityTrigger", testRequest.Event.AccountId);
    }

}

//.NET8 isolated worker entity trigger

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

public class TestEntityTrigger
{
    [Function("TestEntityTrigger")]
    public string TestTrigger([EntityTrigger] TaskEntityDispatcher taskEntityDispatcher, string input) // Input parameter is null here
    {
        return input;
    }
}

The issue I am having is that the .NET8 in-process entity trigger's input is always null and I am not sure what is wrong. I have also tried replacing the TaskEntityDispatcher parameter with other objects based on https://video2.skills-academy.com/en-us/azure/azure-functions/durable/durable-functions-dotnet-isolated-overview stating that the IDurableEntityContext equivalent is TaskEntityContext but that always end with an exception. Any guidance would be greatly appreciated.

Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
4,953 questions
.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,823 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Tony 0 Reputation points
    2024-09-26T21:50:30.1266667+00:00

    I figured it out. In case anyone is curious, you can't access the input from a parameter, it has to come from the TaskEntityDispatcher.

    Here is a basic example:

    public class TestEntityTrigger
    {
        [Function("TestEntityTrigger")]
        public Task TestTrigger([EntityTrigger] TaskEntityDispatcher taskEntityDispatcher) 
        {
            await dispatcher.DispatchAsync(async operation =>
            {
                var input = operation.GetInput<string>();
            
                return await _someService.SomeMethod(input);
            });
        }
    }
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.