async Task <IEnumerable <OrchestratorAction> > ExecuteOrchestrationAsync(OrchestrationRuntimeState runtimeState) { TaskOrchestration taskOrchestration = objectManager.GetObject(runtimeState.Name, runtimeState.Version); if (taskOrchestration == null) { throw TraceHelper.TraceExceptionInstance( TraceEventType.Error, "TaskOrchestrationDispatcher-TypeMissing", runtimeState.OrchestrationInstance, new TypeMissingException($"Orchestration not found: ({runtimeState.Name}, {runtimeState.Version})")); } var dispatchContext = new DispatchMiddlewareContext(); dispatchContext.SetProperty(runtimeState.OrchestrationInstance); dispatchContext.SetProperty(taskOrchestration); dispatchContext.SetProperty(runtimeState); IEnumerable <OrchestratorAction> decisions = null; await this.dispatchPipeline.RunAsync(dispatchContext, _ => { var taskOrchestrationExecutor = new TaskOrchestrationExecutor(runtimeState, taskOrchestration); decisions = taskOrchestrationExecutor.Execute(); return(Task.FromResult(0)); }); return(decisions); }
async Task <T> Execute <T>(FakeOrchestrationContext context, string name, string version, object input) { OrchestrationInstance instance = context.OrchestrationInstance; SynchronizationContext prevCtx = SynchronizationContext.Current; try { TaskOrchestration definition = orchestrationObjectManager.GetObject(name, version); if (definition == null) { throw new OrchestrationFrameworkException("Orchestration not found"); } string serializedInput = dataConverter.Serialize(input); Task <string> serializedResultTask = definition.Execute(context, serializedInput); currentExecutions.Add(instance.InstanceId, definition); string serializedResult = null; try { serializedResult = await serializedResultTask; } catch (OrchestrationFailureException e) { Exception cause = Utils.RetrieveCause(e.Details, dataConverter); var subOrchestrationFailedException = new SubOrchestrationFailedException(0, 0, name, version, e.Message, cause); throw subOrchestrationFailedException; } catch (Exception e) { var subOrchestrationFailedException = new SubOrchestrationFailedException(0, 0, name, version, e.Message, e); throw subOrchestrationFailedException; } return(dataConverter.Deserialize <T>(serializedResult)); } finally { SynchronizationContext.SetSynchronizationContext(prevCtx); TaskOrchestration orchestration = null; if (currentExecutions.TryGetValue(instance.InstanceId, out orchestration)) { currentExecutions.Remove(instance.InstanceId); completedExecutions.Add(instance, orchestration); } } }
async Task OnProcessWorkItemAsync(TaskActivityWorkItem workItem) { Task renewTask = null; var renewCancellationTokenSource = new CancellationTokenSource(); try { TaskMessage taskMessage = workItem.TaskMessage; OrchestrationInstance orchestrationInstance = taskMessage.OrchestrationInstance; if (string.IsNullOrWhiteSpace(orchestrationInstance?.InstanceId)) { throw TraceHelper.TraceException( TraceEventType.Error, "TaskActivityDispatcher-MissingOrchestrationInstance", new InvalidOperationException("Message does not contain any OrchestrationInstance information")); } if (taskMessage.Event.EventType != EventType.TaskScheduled) { throw TraceHelper.TraceException( TraceEventType.Critical, "TaskActivityDispatcher-UnsupportedEventType", new NotSupportedException("Activity worker does not support event of type: " + taskMessage.Event.EventType)); } // call and get return message var scheduledEvent = (TaskScheduledEvent)taskMessage.Event; TaskActivity taskActivity = objectManager.GetObject(scheduledEvent.Name, scheduledEvent.Version); if (taskActivity == null) { throw new TypeMissingException($"TaskActivity {scheduledEvent.Name} version {scheduledEvent.Version} was not found"); } renewTask = Task.Factory.StartNew(() => RenewUntil(workItem, renewCancellationTokenSource.Token)); // TODO : pass workflow instance data var context = new TaskContext(taskMessage.OrchestrationInstance); HistoryEvent eventToRespond = null; var dispatchContext = new DispatchMiddlewareContext(); dispatchContext.SetProperty(taskMessage.OrchestrationInstance); dispatchContext.SetProperty(taskActivity); dispatchContext.SetProperty(scheduledEvent); await this.dispatchPipeline.RunAsync(dispatchContext, async _ => { try { string output = await taskActivity.RunAsync(context, scheduledEvent.Input); eventToRespond = new TaskCompletedEvent(-1, scheduledEvent.EventId, output); } catch (TaskFailureException e) { TraceHelper.TraceExceptionInstance(TraceEventType.Error, "TaskActivityDispatcher-ProcessTaskFailure", taskMessage.OrchestrationInstance, e); string details = IncludeDetails ? e.Details : null; eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details); } catch (Exception e) when(!Utils.IsFatal(e)) { TraceHelper.TraceExceptionInstance(TraceEventType.Error, "TaskActivityDispatcher-ProcessException", taskMessage.OrchestrationInstance, e); string details = IncludeDetails ? $"Unhandled exception while executing task: {e}\n\t{e.StackTrace}" : null; eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details); } }); var responseTaskMessage = new TaskMessage { Event = eventToRespond, OrchestrationInstance = orchestrationInstance }; await this.orchestrationService.CompleteTaskActivityWorkItemAsync(workItem, responseTaskMessage); } finally { if (renewTask != null) { renewCancellationTokenSource.Cancel(); renewTask.Wait(); } } }
protected override async Task OnProcessWorkItem(BrokeredMessage message) { Utils.CheckAndLogDeliveryCount(message, taskHubDescription.MaxTaskActivityDeliveryCount, this.orchestratorQueueName); Task renewTask = null; var renewCancellationTokenSource = new CancellationTokenSource(); try { 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 (taskMessage.Event.EventType != EventType.TaskScheduled) { throw TraceHelper.TraceException(TraceEventType.Critical, new NotSupportedException("Activity worker does not support event of type: " + taskMessage.Event.EventType)); } // call and get return message var scheduledEvent = (TaskScheduledEvent)taskMessage.Event; TaskActivity taskActivity = objectManager.GetObject(scheduledEvent.Name, scheduledEvent.Version); if (taskActivity == null) { throw new TypeMissingException("TaskActivity " + scheduledEvent.Name + " version " + scheduledEvent.Version + " was not found"); } renewTask = Task.Factory.StartNew(() => RenewUntil(message, renewCancellationTokenSource.Token)); // TODO : pass workflow instance data var context = new TaskContext(taskMessage.OrchestrationInstance); HistoryEvent eventToRespond = null; try { string output = await taskActivity.RunAsync(context, scheduledEvent.Input); eventToRespond = new TaskCompletedEvent(-1, scheduledEvent.EventId, output); } catch (TaskFailureException e) { TraceHelper.TraceExceptionInstance(TraceEventType.Error, taskMessage.OrchestrationInstance, e); string details = IncludeDetails ? e.Details : null; eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details); } catch (Exception e) { TraceHelper.TraceExceptionInstance(TraceEventType.Error, taskMessage.OrchestrationInstance, e); string details = IncludeDetails ? string.Format("Unhandled exception while executing task: {0}\n\t{1}", e, e.StackTrace) : null; eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details); } var responseTaskMessage = new TaskMessage(); responseTaskMessage.Event = eventToRespond; responseTaskMessage.OrchestrationInstance = orchestrationInstance; BrokeredMessage responseMessage = Utils.GetBrokeredMessageFromObject(responseTaskMessage, settings.MessageCompressionSettings, orchestrationInstance, "Response for " + message.MessageId); responseMessage.SessionId = orchestrationInstance.InstanceId; using (var ts = new TransactionScope()) { workerQueueClient.Complete(message.LockToken); deciderSender.Send(responseMessage); ts.Complete(); } } finally { if (renewTask != null) { renewCancellationTokenSource.Cancel(); renewTask.Wait(); } } }