Azure / azure-functions-durable-extension

Durable Task Framework extension for Azure Functions
MIT License
717 stars 271 forks source link

WaitForExternalEvent doesn't remove consumed message on queue when sending messages with the same name #2735

Open taoweng1000 opened 9 months ago

taoweng1000 commented 9 months ago

I have an orchestrator function that continuously WaitForExternalEvent with the name "Events". If a new event is received, it will process it. What I'm seeing is that the WaitForExternalEvent never removes the consumed message, is this the expected behavior?

public static class Orchestrator
{
    [FunctionName("Orchestrator")]
    public static async Task<List<string>> RunOrchestrator(
        [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log)
    {
        while ( true ) {
            string eventString = await context.WaitForExternalEvent<string>("Events");

            log.LogInformation(eventString);

        }
    }
}        

Here is what shows in the log: client sends Event1 console displays Event1

client sends Event2 console displays Event1 console displays Event2

client sends Event3 console displays Event1 console displays Event2 console displays Event3

taoweng1000 commented 9 months ago
<TargetFramework>net6.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.EventHubs" Version="5.5.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.2.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DurableTask" Version="2.13.1" />

Reading the documentation, it seems supported since version 1.x...but with my setup, I couldn't get it working. consumed events are not deleted.

olitomlinson commented 9 months ago

@taoweng1000

if your orchestration should run indefinitely, it would be a candidate for the Eternal Orchestration Pattern

https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-eternal-orchestrations?tabs=csharp

This is a more efficient pattern that doing a while loop, and I dare say it may handle events in a better way as per your expectations - it's worth trying

ltouro commented 9 months ago

It seems you are bumping into the replay pattern from the framework.

Make sure that you use a logger that is aware of that so that you don't see duplicated logs:

ILogger logger = context.CreateReplaySafeLogger(log);

Reference: https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-diagnostics?tabs=csharp-inproc#app-logging