in src/DurableTask.Core/TaskOrchestrationDispatcher.cs [921:1032]
TaskMessage? ProcessWorkflowCompletedTaskDecision(
OrchestrationCompleteOrchestratorAction completeOrchestratorAction,
OrchestrationRuntimeState runtimeState,
bool includeDetails,
out bool continuedAsNew)
{
ExecutionCompletedEvent executionCompletedEvent;
continuedAsNew = (completeOrchestratorAction.OrchestrationStatus == OrchestrationStatus.ContinuedAsNew);
if (completeOrchestratorAction.OrchestrationStatus == OrchestrationStatus.ContinuedAsNew)
{
executionCompletedEvent = new ContinueAsNewEvent(completeOrchestratorAction.Id,
completeOrchestratorAction.Result);
}
else
{
executionCompletedEvent = new ExecutionCompletedEvent(completeOrchestratorAction.Id,
completeOrchestratorAction.Result,
completeOrchestratorAction.OrchestrationStatus,
completeOrchestratorAction.FailureDetails);
}
runtimeState.AddEvent(executionCompletedEvent);
this.logHelper.OrchestrationCompleted(runtimeState, completeOrchestratorAction);
TraceHelper.TraceInstance(
runtimeState.OrchestrationStatus == OrchestrationStatus.Failed ? TraceEventType.Warning : TraceEventType.Information,
"TaskOrchestrationDispatcher-InstanceCompleted",
runtimeState.OrchestrationInstance!,
"Instance Id '{0}' completed in state {1} with result: {2}",
runtimeState.OrchestrationInstance!,
runtimeState.OrchestrationStatus,
completeOrchestratorAction.Result ?? "");
TraceHelper.TraceInstance(
TraceEventType.Information,
"TaskOrchestrationDispatcher-InstanceCompletionEvents",
runtimeState.OrchestrationInstance!,
() => Utils.EscapeJson(JsonDataConverter.Default.Serialize(runtimeState.GetOrchestrationRuntimeStateDump(), true)));
// Check to see if we need to start a new execution
if (completeOrchestratorAction.OrchestrationStatus == OrchestrationStatus.ContinuedAsNew)
{
var taskMessage = new TaskMessage();
var startedEvent = new ExecutionStartedEvent(-1, completeOrchestratorAction.Result)
{
OrchestrationInstance = new OrchestrationInstance
{
InstanceId = runtimeState.OrchestrationInstance!.InstanceId,
ExecutionId = Guid.NewGuid().ToString("N")
},
Tags = runtimeState.Tags,
ParentInstance = runtimeState.ParentInstance,
Name = runtimeState.Name,
Version = completeOrchestratorAction.NewVersion ?? runtimeState.Version
};
taskMessage.OrchestrationInstance = startedEvent.OrchestrationInstance;
taskMessage.Event = startedEvent;
return taskMessage;
}
// If this is a Sub Orchestration, and not tagged as fire-and-forget,
// then notify the parent by sending a complete message
if (runtimeState.ParentInstance != null
&& !OrchestrationTags.IsTaggedAsFireAndForget(runtimeState.Tags))
{
var taskMessage = new TaskMessage();
if (completeOrchestratorAction.OrchestrationStatus == OrchestrationStatus.Completed)
{
var subOrchestrationCompletedEvent =
new SubOrchestrationInstanceCompletedEvent(-1, runtimeState.ParentInstance.TaskScheduleId,
completeOrchestratorAction.Result);
taskMessage.Event = subOrchestrationCompletedEvent;
}
else if (completeOrchestratorAction.OrchestrationStatus == OrchestrationStatus.Failed ||
completeOrchestratorAction.OrchestrationStatus == OrchestrationStatus.Terminated)
{
var subOrchestrationFailedEvent =
new SubOrchestrationInstanceFailedEvent(-1, runtimeState.ParentInstance.TaskScheduleId,
completeOrchestratorAction.Result,
includeDetails ? completeOrchestratorAction.Details : null);
subOrchestrationFailedEvent.FailureDetails = completeOrchestratorAction.FailureDetails;
taskMessage.Event = subOrchestrationFailedEvent;
if (completeOrchestratorAction.OrchestrationStatus == OrchestrationStatus.Failed)
{
DistributedTraceActivity.Current?.SetStatus(
ActivityStatusCode.Error, completeOrchestratorAction.Result);
}
}
ResetDistributedTraceActivity(runtimeState);
if (taskMessage.Event != null)
{
taskMessage.OrchestrationInstance = runtimeState.ParentInstance.OrchestrationInstance;
return taskMessage;
}
}
if (completeOrchestratorAction.OrchestrationStatus == OrchestrationStatus.Failed)
{
DistributedTraceActivity.Current?.SetStatus(
ActivityStatusCode.Error, completeOrchestratorAction.Result);
}
ResetDistributedTraceActivity(runtimeState);
return null;
}