About the "at-least-onces" message delivery guarantee for Activity Functions (DurableFunctions) #2203
-
This question originated from an issue I opened and closed where I got some help from @davidmrdavid. After an email I sent regarding another question I had about the "at-least-once" message delivery guarantee we aggreed that it would be best if this was posted in the forums so that others can make use of the knowledge shared in the answer. How does the guarantee work? Let's say I call the same activity function several times, just how does Azure or the Durable Function know that the activity has or has not been made? Example:Here is how the DurableOrchestrationContext calls the function: for (int i = 0; i < numbers.Count; i++)
{
outputs.Add(await context.CallActivityAsync<string>("PrintNumber", numbers[i].ToString()));
} And here is the function itself: [FunctionName("PrintNumber")]
public static async Task<string> SayHello([ActivityTrigger] string number, ILogger log)
{
log.LogInformation($"Printed number: {number}.");
return $"Printed {number}!";
} This is how the function calls are stored inside of Azure Storage: So my question is, what it is it that the durable extension framework does to make sure that it has executed call 0, 1, 2, 3, 4 to PrintNumber with the value in the array? I also have a side question, if the Activity Function times out due to it reaching the max limit.. Will the Durable Function just keep rescheduling it over & over again or does it have a limit for retries? Or does the Durable Function also time out after a while? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
The framework uses sequence numbers to know whether an activity has been scheduled. These numbers always start from 0 and are incremented by 1 for each new task that is scheduled. When processing the history, the framework checks to see if a call to
Today, we retry forever. However, we're looking into adding a Poison message feature that will help in cases where retrying forever is not desirable. |
Beta Was this translation helpful? Give feedback.
The framework uses sequence numbers to know whether an activity has been scheduled. These numbers always start from 0 and are incremented by 1 for each new task that is scheduled. When processing the history, the framework checks to see if a call to
CallActivityAsync
has a correspondingTaskScheduledEvent
already. If it doesn't then we know it hasn't been scheduled yet. If it does, then we know it's already been scheduled and we're just waiting for a response. There is also aTaskCompletedEvent
that corresponds to everyTaskScheduledEvent
…