in src/DurableSDK/DurableTaskHandler.cs [18:103]
public void StopAndInitiateDurableTaskOrReplay(
DurableTask task,
OrchestrationContext context,
bool noWait,
Action<object> output,
Action<string> onFailure,
RetryOptions retryOptions = null)
{
context.OrchestrationActionCollector.Add(task.CreateOrchestrationAction());
if (noWait)
{
output(task);
}
else
{
context.OrchestrationActionCollector.NextBatch();
var scheduledHistoryEvent = task.GetScheduledHistoryEvent(context);
var completedHistoryEvent = task.GetCompletedHistoryEvent(context, scheduledHistoryEvent);
// We must check if the task has been completed first, otherwise external events will always wait upon replays
if (completedHistoryEvent != null)
{
CurrentUtcDateTimeUpdater.UpdateCurrentUtcDateTime(context);
if (scheduledHistoryEvent != null)
{
scheduledHistoryEvent.IsProcessed = true;
}
completedHistoryEvent.IsProcessed = true;
context.IsReplaying = completedHistoryEvent.IsPlayed;
switch (completedHistoryEvent.EventType)
{
case HistoryEventType.TaskCompleted:
var eventResult = GetEventResult(completedHistoryEvent);
if (eventResult != null)
{
output(eventResult);
}
break;
case HistoryEventType.EventRaised:
var eventRaisedResult = GetEventResult(completedHistoryEvent);
if (eventRaisedResult != null)
{
output(eventRaisedResult);
}
break;
case HistoryEventType.TaskFailed:
if (retryOptions == null)
{
onFailure(completedHistoryEvent.Reason);
}
else
{
// Reset IsProcessed, let RetryProcessor handle these events instead.
scheduledHistoryEvent.IsProcessed = false;
completedHistoryEvent.IsProcessed = false;
var shouldContinueProcessing =
RetryProcessor.Process(
context.History,
scheduledHistoryEvent,
retryOptions.MaxNumberOfAttempts,
onSuccess:
result => {
output(TypeExtensions.ConvertFromJson(result));
},
onFailure);
if (shouldContinueProcessing)
{
InitiateAndWaitForStop(context);
}
}
break;
}
}
else
{
InitiateAndWaitForStop(context);
}
}
}