in src/DurableTask.Core/TaskOrchestrationDispatcher.cs [151:202]
void EnsureExecutionStartedIsFirst(IList<TaskMessage> batch)
{
// We look for *the first* instance of an ExecutionStarted event in the batch, if any.
int index = 0;
string previousExecutionId = "";
int targetPosition = 0; // new position of ExecutionStarted in case of a re-ordering
TaskMessage? executionStartedEvent = null;
foreach (TaskMessage message in batch)
{
// Keep track of orchestrator generation changes, maybe update target position
string executionId = message.OrchestrationInstance.ExecutionId;
if (previousExecutionId != executionId)
{
// We want to re-position the ExecutionStarted event after the "right-most"
// event with a non-null executionID that came before it.
// So, only update target position if the executionID changed
// and the previous executionId was not null.
if (previousExecutionId != null)
{
targetPosition = index;
}
previousExecutionId = executionId;
}
// Find the first ExecutionStarted event.
if (message.Event.EventType == EventType.ExecutionStarted)
{
// ParentInstance needs to be null to avoid re-ordering
// ContinueAsNew events
if ((message.Event is ExecutionStartedEvent eventData) &&
(eventData.ParentInstance == null))
{
executionStartedEvent = message;
}
// We only consider the first ExecutionStarted event in the
// list, so we always break.
break;
}
index++;
}
// If we found an ExecutionStartedEvent, we place it either
// (A) in the beginning or
// (B) after the "right-most" event with non-null executionID that came before it.
int executionStartedIndex = index;
if ((executionStartedEvent != null) && (executionStartedIndex != targetPosition))
{
batch.RemoveAt(executionStartedIndex);
batch.Insert(targetPosition, executionStartedEvent);
}
}