public void StopAndInitiateDurableTaskOrReplay()

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);
                }
            }
        }