async Task <bool> ReconcileMessagesWithStateAsync(string sessionId, OrchestrationRuntimeState runtimeState, IEnumerable <BrokeredMessage> messages) { foreach (BrokeredMessage message in messages) { Utils.CheckAndLogDeliveryCount( sessionId, message, taskHubDescription.MaxTaskOrchestrationDeliveryCount, this.orchestratorEntityName); TaskMessage taskMessage = await Utils.GetObjectFromBrokeredMessageAsync <TaskMessage>(message); OrchestrationInstance orchestrationInstance = taskMessage.OrchestrationInstance; if (orchestrationInstance == null || string.IsNullOrWhiteSpace(orchestrationInstance.InstanceId)) { throw TraceHelper.TraceException(TraceEventType.Error, new InvalidOperationException("Message does not contain any OrchestrationInstance information")); } if (runtimeState.Events.Count == 1 && taskMessage.Event.EventType != EventType.ExecutionStarted) { // we get here because of: // i) responses for scheduled tasks after the orchestrations have been completed // ii) responses for explicitly deleted orchestrations return(false); } TraceHelper.TraceInstance(TraceEventType.Information, orchestrationInstance, "Processing new event with Id {0} and type {1}", taskMessage.Event.EventId, taskMessage.Event.EventType); if (taskMessage.Event.EventType == EventType.ExecutionStarted) { if (runtimeState.Events.Count > 1) { // this was caused due to a dupe execution started event, swallow this one TraceHelper.TraceInstance(TraceEventType.Warning, orchestrationInstance, "Duplicate start event. Ignoring event with Id {0} and type {1} ", taskMessage.Event.EventId, taskMessage.Event.EventType); continue; } } else if (!string.IsNullOrWhiteSpace(orchestrationInstance.ExecutionId) && !string.Equals(orchestrationInstance.ExecutionId, runtimeState.OrchestrationInstance.ExecutionId)) { // eat up any events for previous executions TraceHelper.TraceInstance(TraceEventType.Warning, orchestrationInstance, "ExecutionId of event does not match current executionId. Ignoring event with Id {0} and type {1} ", taskMessage.Event.EventId, taskMessage.Event.EventType); continue; } runtimeState.AddEvent(taskMessage.Event); } return(true); }
static TaskMessage ProcessCreateTimerDecision( CreateTimerOrchestratorAction createTimerOrchestratorAction, OrchestrationRuntimeState runtimeState) { var taskMessage = new TaskMessage(); var timerCreatedEvent = new TimerCreatedEvent(createTimerOrchestratorAction.Id); timerCreatedEvent.FireAt = createTimerOrchestratorAction.FireAt; runtimeState.AddEvent(timerCreatedEvent); var timerFiredEvent = new TimerFiredEvent(-1); timerFiredEvent.TimerId = createTimerOrchestratorAction.Id; taskMessage.Event = timerFiredEvent; taskMessage.OrchestrationInstance = runtimeState.OrchestrationInstance; return(taskMessage); }
static TaskMessage ProcessCreateSubOrchestrationInstanceDecision( CreateSubOrchestrationAction createSubOrchestrationAction, OrchestrationRuntimeState runtimeState, bool includeParameters) { var historyEvent = new SubOrchestrationInstanceCreatedEvent(createSubOrchestrationAction.Id); historyEvent.Name = createSubOrchestrationAction.Name; historyEvent.Version = createSubOrchestrationAction.Version; historyEvent.InstanceId = createSubOrchestrationAction.InstanceId; if (includeParameters) { historyEvent.Input = createSubOrchestrationAction.Input; } runtimeState.AddEvent(historyEvent); var taskMessage = new TaskMessage(); var startedEvent = new ExecutionStartedEvent(-1, createSubOrchestrationAction.Input); startedEvent.Tags = runtimeState.Tags; startedEvent.OrchestrationInstance = new OrchestrationInstance { InstanceId = createSubOrchestrationAction.InstanceId, ExecutionId = Guid.NewGuid().ToString("N") }; startedEvent.ParentInstance = new ParentInstance { OrchestrationInstance = runtimeState.OrchestrationInstance, Name = runtimeState.Name, Version = runtimeState.Version, TaskScheduleId = createSubOrchestrationAction.Id }; startedEvent.Name = createSubOrchestrationAction.Name; startedEvent.Version = createSubOrchestrationAction.Version; taskMessage.OrchestrationInstance = startedEvent.OrchestrationInstance; taskMessage.Event = startedEvent; return(taskMessage); }
static TaskMessage ProcessScheduleTaskDecision( ScheduleTaskOrchestratorAction scheduleTaskOrchestratorAction, OrchestrationRuntimeState runtimeState, bool includeParameters) { var taskMessage = new TaskMessage(); var scheduledEvent = new TaskScheduledEvent(scheduleTaskOrchestratorAction.Id); scheduledEvent.Name = scheduleTaskOrchestratorAction.Name; scheduledEvent.Version = scheduleTaskOrchestratorAction.Version; scheduledEvent.Input = scheduleTaskOrchestratorAction.Input; taskMessage.Event = scheduledEvent; taskMessage.OrchestrationInstance = runtimeState.OrchestrationInstance; if (!includeParameters) { scheduledEvent = new TaskScheduledEvent(scheduleTaskOrchestratorAction.Id); scheduledEvent.Name = scheduleTaskOrchestratorAction.Name; scheduledEvent.Version = scheduleTaskOrchestratorAction.Version; } runtimeState.AddEvent(scheduledEvent); return(taskMessage); }
static 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); } runtimeState.AddEvent(executionCompletedEvent); TraceHelper.TraceInstance(TraceEventType.Information, runtimeState.OrchestrationInstance, "Instance Id '{0}' completed in state {1} with result: {2}", runtimeState.OrchestrationInstance, runtimeState.OrchestrationStatus, completeOrchestratorAction.Result); string history = JsonConvert.SerializeObject(runtimeState.Events, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects }); TraceHelper.TraceInstance(TraceEventType.Information, runtimeState.OrchestrationInstance, () => Utils.EscapeJson(history)); // 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); startedEvent.OrchestrationInstance = new OrchestrationInstance { InstanceId = runtimeState.OrchestrationInstance.InstanceId, ExecutionId = Guid.NewGuid().ToString("N") }; startedEvent.Tags = runtimeState.Tags; startedEvent.ParentInstance = runtimeState.ParentInstance; startedEvent.Name = runtimeState.Name; startedEvent.Version = completeOrchestratorAction.NewVersion ?? runtimeState.Version; taskMessage.OrchestrationInstance = startedEvent.OrchestrationInstance; taskMessage.Event = startedEvent; return(taskMessage); } // If this is a Sub Orchestration than notify the parent by sending a complete message if (runtimeState.ParentInstance != null) { 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); taskMessage.Event = subOrchestrationFailedEvent; } if (taskMessage.Event != null) { taskMessage.OrchestrationInstance = runtimeState.ParentInstance.OrchestrationInstance; return(taskMessage); } } return(null); }