'Calling Two Durable Entity Methods in same Orchestration causes orchestration to hang and use up all memory
I have an orchestration which creates multiple tasks within a third-party system. So I want to initialise their status in a durable entity and then as they complete within the third-party system (via callback into my orchestration), update their status and then once all tasks are complete, finish my orchestration. Therefore, within one orchestration I want to update the status of a third-party task in my entity and then check whether all tasks are complete (according to my entity). If I try to execute both methods within the same orchestration my orchestration hangs and slowly uses up all memory and crashes.
My Entity
public class OrchestrationData : IOrchestrationData
{
[JsonProperty("taskStatuses")]
public List<TaskStatus> TaskStatuses { get; set; } = new List<TaskStatus>();
[FunctionName(nameof(OrchestrationData))]
public static Task Run([EntityTrigger] IDurableEntityContext context)
=> context.DispatchAsync<OrchestrationData>();
public Task<bool> AllTasksCompleteAsync()
{
return Task.FromResult(TaskStatuses.All(ts => ts.WorkflowStep == WfStep.Complete));
}
public Task SetTaskStatusAsync(TaskStatus status)
{
return Task.Run(() =>
{
if (TaskStatuses.SingleOrDefault(ts => ts.LanguageCode.Equals(status.LanguageCode)) == null)
{
TaskStatuses.Add(status);
}
else
{
TaskStatuses.Single(ts => ts.LanguageCode.Equals(status.LanguageCode))
.WorkflowStep = status.WorkflowStep;
}
});
}
}
My Orchestrator
...
EntityId entityId = new EntityId(nameof(OrchestrationData), TaskIdentifier.ToString());
IOrchestrationData proxy = context.CreateEntityProxy<IOrchestrationData>(entityId);
// Having this
await proxy.SetTaskStatus(new TaskStatus(LanguageCode(), WfStep.Complete));
// OR this
bool areAllTasksComplete = await proxy.AllTaskCompleteAsync();
// executes okay - if both then orchestration goes crazy
if (areAllTasksComplete)
{
// do stuff
}
...
I would expect this to be fine particularly as they are both awaited.
Update
After crashing if I look at the state of the durable entity it has a "Buffered": property so I guess there's a concurrency problem although I thought durable entities guaranteed processing of messages one at a time.
If I move the SetTaskStatus() call to another new Activity function then it appears to work.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
