public void HandleTaskScheduledEvent(TaskScheduledEvent scheduledEvent)
        {
            int taskId = scheduledEvent.EventId;

            if (this.orchestratorActionsMap.ContainsKey(taskId))
            {
                this.orchestratorActionsMap.Remove(taskId);
            }
            else
            {
                throw new NonDeterministicOrchestrationException(scheduledEvent.EventId,
                                                                 $"TaskScheduledEvent: {scheduledEvent.EventId} {scheduledEvent.EventType} {scheduledEvent.Name} {scheduledEvent.Version}");
            }
        }
        public void HandleTaskScheduledEvent(TaskScheduledEvent scheduledEvent)
        {
            int taskId = scheduledEvent.EventId;

            if (orchestratorActionsMap.ContainsKey(taskId))
            {
                orchestratorActionsMap.Remove(taskId);
            }
            else
            {
                throw new NonDeterministicOrchestrationException(scheduledEvent.EventId,
                                                                 string.Format("TaskScheduledEvent: {0} {1} {2} {3}",
                                                                               scheduledEvent.EventId, scheduledEvent.EventType, scheduledEvent.Name, scheduledEvent.Version));
            }
        }
        public async Task DispatchMiddlewareContextBuiltInProperties()
        {
            TaskOrchestration         orchestration = null;
            OrchestrationRuntimeState state         = null;
            OrchestrationInstance     instance1     = null;

            TaskActivity          activity           = null;
            TaskScheduledEvent    taskScheduledEvent = null;
            OrchestrationInstance instance2          = null;

            this.worker.AddOrchestrationDispatcherMiddleware((context, next) =>
            {
                orchestration = context.GetProperty <TaskOrchestration>();
                state         = context.GetProperty <OrchestrationRuntimeState>();
                instance1     = context.GetProperty <OrchestrationInstance>();

                return(next());
            });

            this.worker.AddActivityDispatcherMiddleware((context, next) =>
            {
                activity           = context.GetProperty <TaskActivity>();
                taskScheduledEvent = context.GetProperty <TaskScheduledEvent>();
                instance2          = context.GetProperty <OrchestrationInstance>();

                return(next());
            });

            var instance = await this.client.CreateOrchestrationInstanceAsync(typeof(SimplestGreetingsOrchestration), null);

            TimeSpan timeout = TimeSpan.FromSeconds(Debugger.IsAttached ? 1000 : 10);

            await this.client.WaitForOrchestrationAsync(instance, timeout);

            Assert.IsNotNull(orchestration);
            Assert.IsNotNull(state);
            Assert.IsNotNull(instance1);

            Assert.IsNotNull(activity);
            Assert.IsNotNull(taskScheduledEvent);
            Assert.IsNotNull(instance2);

            Assert.AreNotSame(instance1, instance2);
            Assert.AreEqual(instance1.InstanceId, instance2.InstanceId);
        }
示例#4
0
        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);
        }
示例#5
0
        public override async Task <TResult> CallActivityAsync <TResult>(string functionName, object input)
        {
            var taskScheduled = new TaskScheduledEvent(History.Count)
            {
                Name = functionName
            };

            History.Add(taskScheduled);

            try
            {
                var result = await CallActivityFunctionByNameAsync(functionName, input);

                History.Add(new TaskCompletedEvent(History.Count, taskScheduled.EventId,
                                                   JsonConvert.SerializeObject(result)));

                return(result);
            }
            catch (Exception ex)
            {
                History.Add(new TaskFailedEvent(History.Count, taskScheduled.EventId, ex.Message, ex.StackTrace));
                throw;
            }
        }
        HistoryEvent GenerateAbridgedEvent(HistoryEvent evt)
        {
            HistoryEvent returnedEvent = evt;

            if (evt is TaskScheduledEvent)
            {
                var sourceEvent = (TaskScheduledEvent) evt;
                returnedEvent = new TaskScheduledEvent(sourceEvent.EventId)
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                    Name = sourceEvent.Name,
                    Version = sourceEvent.Version,
                    Input = "[..snipped..]",
                };
            }
            else if (evt is TaskCompletedEvent)
            {
                var sourceEvent = (TaskCompletedEvent) evt;
                returnedEvent = new TaskCompletedEvent(sourceEvent.EventId, sourceEvent.TaskScheduledId, "[..snipped..]")
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            else if (evt is SubOrchestrationInstanceCreatedEvent)
            {
                var sourceEvent = (SubOrchestrationInstanceCreatedEvent) evt;
                returnedEvent = new SubOrchestrationInstanceCreatedEvent(sourceEvent.EventId)
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                    Name = sourceEvent.Name,
                    Version = sourceEvent.Version,
                    Input = "[..snipped..]",
                };
            }
            else if (evt is SubOrchestrationInstanceCompletedEvent)
            {
                var sourceEvent = (SubOrchestrationInstanceCompletedEvent) evt;
                returnedEvent = new SubOrchestrationInstanceCompletedEvent(sourceEvent.EventId,
                    sourceEvent.TaskScheduledId, "[..snipped..]")
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            else if (evt is TaskFailedEvent)
            {
                var sourceEvent = (TaskFailedEvent) evt;
                returnedEvent = new TaskFailedEvent(sourceEvent.EventId,
                    sourceEvent.TaskScheduledId, sourceEvent.Reason, "[..snipped..]")
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            else if (evt is SubOrchestrationInstanceFailedEvent)
            {
                var sourceEvent = (SubOrchestrationInstanceFailedEvent) evt;
                returnedEvent = new SubOrchestrationInstanceFailedEvent(sourceEvent.EventId,
                    sourceEvent.TaskScheduledId, sourceEvent.Reason, "[..snipped..]")
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            else if (evt is ExecutionStartedEvent)
            {
                var sourceEvent = (ExecutionStartedEvent) evt;
                returnedEvent = new ExecutionStartedEvent(sourceEvent.EventId, "[..snipped..]")
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            else if (evt is ExecutionCompletedEvent)
            {
                var sourceEvent = (ExecutionCompletedEvent) evt;
                returnedEvent = new ExecutionCompletedEvent(sourceEvent.EventId, "[..snipped..]",
                    sourceEvent.OrchestrationStatus)
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            else if (evt is ExecutionTerminatedEvent)
            {
                var sourceEvent = (ExecutionTerminatedEvent) evt;
                returnedEvent = new ExecutionTerminatedEvent(sourceEvent.EventId, "[..snipped..]")
                {
                    Timestamp = sourceEvent.Timestamp,
                    IsPlayed = sourceEvent.IsPlayed,
                };
            }
            // ContinueAsNewEvent is covered by the ExecutionCompletedEvent block

            return returnedEvent;
        }
 public ExtendedActivityWorkItem(TaskScheduledEvent scheduledEvent)
 {
     this.ScheduledEvent = scheduledEvent;
 }
        async Task OnProcessWorkItemAsync(TaskActivityWorkItem workItem)
        {
            Task renewTask = null;
            var  renewCancellationTokenSource = new CancellationTokenSource();

            TaskMessage           taskMessage           = workItem.TaskMessage;
            OrchestrationInstance orchestrationInstance = taskMessage.OrchestrationInstance;
            TaskScheduledEvent    scheduledEvent        = null;
            Activity diagnosticActivity = null;

            try
            {
                if (string.IsNullOrWhiteSpace(orchestrationInstance?.InstanceId))
                {
                    this.logHelper.TaskActivityDispatcherError(
                        workItem,
                        $"The activity worker received a message that does not have any OrchestrationInstance information.");
                    throw TraceHelper.TraceException(
                              TraceEventType.Error,
                              "TaskActivityDispatcher-MissingOrchestrationInstance",
                              new InvalidOperationException("Message does not contain any OrchestrationInstance information"));
                }

                if (taskMessage.Event.EventType != EventType.TaskScheduled)
                {
                    this.logHelper.TaskActivityDispatcherError(
                        workItem,
                        $"The activity worker received an event of type '{taskMessage.Event.EventType}' but only '{EventType.TaskScheduled}' is supported.");
                    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
                scheduledEvent = (TaskScheduledEvent)taskMessage.Event;
                this.logHelper.TaskActivityStarting(orchestrationInstance, scheduledEvent);
                TaskActivity taskActivity = this.objectManager.GetObject(scheduledEvent.Name, scheduledEvent.Version);
                if (taskActivity == null)
                {
                    throw new TypeMissingException($"TaskActivity {scheduledEvent.Name} version {scheduledEvent.Version} was not found");
                }

                if (workItem.LockedUntilUtc < DateTime.MaxValue)
                {
                    // start a task to run RenewUntil
                    renewTask = Task.Factory.StartNew(
                        () => this.RenewUntil(workItem, renewCancellationTokenSource.Token),
                        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);

                // correlation
                CorrelationTraceClient.Propagate(() =>
                {
                    workItem.TraceContextBase?.SetActivityToCurrent();
                    diagnosticActivity = workItem.TraceContextBase?.CurrentActivity;
                });

                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 = this.IncludeDetails ? e.Details : null;
                        eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details);
                        this.logHelper.TaskActivityFailure(orchestrationInstance, scheduledEvent.Name, (TaskFailedEvent)eventToRespond, e);
                        CorrelationTraceClient.Propagate(() => CorrelationTraceClient.TrackException(e));
                    }
                    catch (Exception e) when(!Utils.IsFatal(e) && !Utils.IsExecutionAborting(e))
                    {
                        TraceHelper.TraceExceptionInstance(TraceEventType.Error, "TaskActivityDispatcher-ProcessException", taskMessage.OrchestrationInstance, e);
                        string details = this.IncludeDetails
                            ? $"Unhandled exception while executing task: {e}\n\t{e.StackTrace}"
                            : null;
                        eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details);
                        this.logHelper.TaskActivityFailure(orchestrationInstance, scheduledEvent.Name, (TaskFailedEvent)eventToRespond, e);
                    }

                    if (eventToRespond is TaskCompletedEvent completedEvent)
                    {
                        this.logHelper.TaskActivityCompleted(orchestrationInstance, scheduledEvent.Name, completedEvent);
                    }
                });

                var responseTaskMessage = new TaskMessage
                {
                    Event = eventToRespond,
                    OrchestrationInstance = orchestrationInstance
                };

                await this.orchestrationService.CompleteTaskActivityWorkItemAsync(workItem, responseTaskMessage);
            }
            catch (SessionAbortedException e)
            {
                // The activity aborted its execution
                this.logHelper.TaskActivityAborted(orchestrationInstance, scheduledEvent, e.Message);
                TraceHelper.TraceInstance(TraceEventType.Warning, "TaskActivityDispatcher-ExecutionAborted", orchestrationInstance, "{0}: {1}", scheduledEvent.Name, e.Message);
                await this.orchestrationService.AbandonTaskActivityWorkItemAsync(workItem);
            }
            finally
            {
                diagnosticActivity?.Stop(); // Ensure the activity is stopped here to prevent it from leaking out.
                if (renewTask != null)
                {
                    renewCancellationTokenSource.Cancel();
                    try
                    {
                        // wait the renewTask finish
                        await renewTask;
                    }
                    catch (OperationCanceledException)
                    {
                        // ignore
                    }
                }
            }
        }
        async Task OnProcessWorkItemAsync(TaskActivityWorkItem workItem)
        {
            Task renewTask = null;
            var  renewCancellationTokenSource = new CancellationTokenSource();

            TaskMessage           taskMessage           = workItem.TaskMessage;
            OrchestrationInstance orchestrationInstance = taskMessage.OrchestrationInstance;
            TaskScheduledEvent    scheduledEvent        = null;

            try
            {
                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
                scheduledEvent = (TaskScheduledEvent)taskMessage.Event;
                TaskActivity taskActivity = this.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), 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) && !Utils.IsExecutionAborting(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);
            }
            catch (SessionAbortedException e)
            {
                // The activity aborted its execution
                string activityName = scheduledEvent?.Name ?? "(unknown)";
                TraceHelper.TraceInstance(TraceEventType.Warning, "TaskActivityDispatcher-ExecutionAborted", orchestrationInstance, "{0}: {1}", activityName, e.Message);
                await this.orchestrationService.AbandonTaskActivityWorkItemAsync(workItem);
            }
            finally
            {
                if (renewTask != null)
                {
                    renewCancellationTokenSource.Cancel();
                    try
                    {
                        await renewTask;
                    }
                    catch (OperationCanceledException)
                    {
                        // ignore
                    }
                }
            }
        }
        HistoryEvent GenerateAbridgedEvent(HistoryEvent evt)
        {
            HistoryEvent returnedEvent = evt;

            if (evt is TaskScheduledEvent taskScheduledEvent)
            {
                returnedEvent = new TaskScheduledEvent(taskScheduledEvent.EventId)
                {
                    Timestamp = taskScheduledEvent.Timestamp,
                    IsPlayed  = taskScheduledEvent.IsPlayed,
                    Name      = taskScheduledEvent.Name,
                    Version   = taskScheduledEvent.Version,
                    Input     = "[..snipped..]",
                };
            }
            else if (evt is TaskCompletedEvent taskCompletedEvent)
            {
                returnedEvent = new TaskCompletedEvent(taskCompletedEvent.EventId, taskCompletedEvent.TaskScheduledId, "[..snipped..]")
                {
                    Timestamp = taskCompletedEvent.Timestamp,
                    IsPlayed  = taskCompletedEvent.IsPlayed,
                };
            }
            else if (evt is SubOrchestrationInstanceCreatedEvent subOrchestrationInstanceCreatedEvent)
            {
                returnedEvent = new SubOrchestrationInstanceCreatedEvent(subOrchestrationInstanceCreatedEvent.EventId)
                {
                    Timestamp = subOrchestrationInstanceCreatedEvent.Timestamp,
                    IsPlayed  = subOrchestrationInstanceCreatedEvent.IsPlayed,
                    Name      = subOrchestrationInstanceCreatedEvent.Name,
                    Version   = subOrchestrationInstanceCreatedEvent.Version,
                    Input     = "[..snipped..]",
                };
            }
            else if (evt is SubOrchestrationInstanceCompletedEvent subOrchestrationInstanceCompletedEvent)
            {
                returnedEvent = new SubOrchestrationInstanceCompletedEvent(subOrchestrationInstanceCompletedEvent.EventId,
                                                                           subOrchestrationInstanceCompletedEvent.TaskScheduledId, "[..snipped..]")
                {
                    Timestamp = subOrchestrationInstanceCompletedEvent.Timestamp,
                    IsPlayed  = subOrchestrationInstanceCompletedEvent.IsPlayed,
                };
            }
            else if (evt is TaskFailedEvent taskFailedEvent)
            {
                returnedEvent = new TaskFailedEvent(taskFailedEvent.EventId,
                                                    taskFailedEvent.TaskScheduledId, taskFailedEvent.Reason, "[..snipped..]")
                {
                    Timestamp = taskFailedEvent.Timestamp,
                    IsPlayed  = taskFailedEvent.IsPlayed,
                };
            }
            else if (evt is SubOrchestrationInstanceFailedEvent subOrchestrationInstanceFailedEvent)
            {
                returnedEvent = new SubOrchestrationInstanceFailedEvent(subOrchestrationInstanceFailedEvent.EventId,
                                                                        subOrchestrationInstanceFailedEvent.TaskScheduledId, subOrchestrationInstanceFailedEvent.Reason, "[..snipped..]")
                {
                    Timestamp = subOrchestrationInstanceFailedEvent.Timestamp,
                    IsPlayed  = subOrchestrationInstanceFailedEvent.IsPlayed,
                };
            }
            else if (evt is ExecutionStartedEvent executionStartedEvent)
            {
                returnedEvent = new ExecutionStartedEvent(executionStartedEvent.EventId, "[..snipped..]")
                {
                    Timestamp = executionStartedEvent.Timestamp,
                    IsPlayed  = executionStartedEvent.IsPlayed,
                };
            }
            else if (evt is ExecutionCompletedEvent executionCompletedEvent)
            {
                returnedEvent = new ExecutionCompletedEvent(executionCompletedEvent.EventId, "[..snipped..]",
                                                            executionCompletedEvent.OrchestrationStatus)
                {
                    Timestamp = executionCompletedEvent.Timestamp,
                    IsPlayed  = executionCompletedEvent.IsPlayed,
                };
            }
            else if (evt is ExecutionTerminatedEvent executionTerminatedEvent)
            {
                returnedEvent = new ExecutionTerminatedEvent(executionTerminatedEvent.EventId, "[..snipped..]")
                {
                    Timestamp = executionTerminatedEvent.Timestamp,
                    IsPlayed  = executionTerminatedEvent.IsPlayed,
                };
            }
            // ContinueAsNewEvent is covered by the ExecutionCompletedEvent block

            return(returnedEvent);
        }
        public async Task MockActivityOrchestration()
        {
            // Orchestrator middleware mocks an orchestration that calls one activity
            // and returns the activity result as its own result
            this.worker.AddOrchestrationDispatcherMiddleware((context, next) =>
            {
                OrchestrationRuntimeState state = context.GetProperty <OrchestrationRuntimeState>();

                if (state.NewEvents.OfType <ExecutionStartedEvent>().Any())
                {
                    // Manually schedule an activity execution
                    context.SetProperty(new OrchestratorExecutionResult
                    {
                        Actions = new[]
                        {
                            new ScheduleTaskOrchestratorAction
                            {
                                Name    = "FakeActivity",
                                Version = "FakeActivityVersion",
                                Input   = "SomeInput",
                            }
                        }
                    });
                }
                else
                {
                    // If we get here, it's because the activity completed
                    TaskCompletedEvent taskCompletedEvent = state.NewEvents.OfType <TaskCompletedEvent>().Single();

                    // We know the activity completed at this point
                    context.SetProperty(new OrchestratorExecutionResult
                    {
                        Actions = new[]
                        {
                            new OrchestrationCompleteOrchestratorAction
                            {
                                OrchestrationStatus = OrchestrationStatus.Completed,
                                Result = taskCompletedEvent?.Result,
                            },
                        },
                    });
                }


                // don't call next() - we're short-circuiting the actual orchestration executor logic
                return(Task.FromResult(0));
            });

            // Activity middleware returns a result immediately
            this.worker.AddActivityDispatcherMiddleware((context, next) =>
            {
                TaskScheduledEvent taskScheduledEvent = context.GetProperty <TaskScheduledEvent>();

                // Use the activity parameters as the activity output
                string output = $"{taskScheduledEvent.Name},{taskScheduledEvent.Version},{taskScheduledEvent.Input}";

                context.SetProperty(new ActivityExecutionResult
                {
                    ResponseEvent = new TaskCompletedEvent(-1, taskScheduledEvent.EventId, output),
                });

                // don't call next() - we're short-circuiting the actual activity executor logic
                return(Task.FromResult(0));
            });

            OrchestrationInstance instance = await this.client.CreateOrchestrationInstanceAsync(
                name : "FakeName",
                version : "FakeVersion",
                input : null);

            TimeSpan           timeout = TimeSpan.FromSeconds(Debugger.IsAttached ? 1000 : 5);
            OrchestrationState state   = await this.client.WaitForOrchestrationAsync(instance, timeout);

            Assert.AreEqual(OrchestrationStatus.Completed, state.OrchestrationStatus);
            Assert.AreEqual("FakeActivity,FakeActivityVersion,SomeInput", state.Output);
        }
示例#12
0
        public static HistoryEvent GetHistoryEvent(this DbDataReader reader, bool isOrchestrationHistory = false)
        {
            string eventTypeString = (string)reader["EventType"];

            if (!Enum.TryParse(eventTypeString, out EventType eventType))
            {
                throw new InvalidOperationException($"Unknown event type '{eventTypeString}'.");
            }

            int eventId = GetTaskId(reader);

            HistoryEvent historyEvent;

            switch (eventType)
            {
            case EventType.ContinueAsNew:
                historyEvent = new ContinueAsNewEvent(eventId, GetPayloadText(reader));
                break;

            case EventType.EventRaised:
                historyEvent = new EventRaisedEvent(eventId, GetPayloadText(reader))
                {
                    Name = GetName(reader),
                };
                break;

            case EventType.EventSent:
                historyEvent = new EventSentEvent(eventId)
                {
                    Input      = GetPayloadText(reader),
                    Name       = GetName(reader),
                    InstanceId = GetInstanceId(reader),
                };
                break;

            case EventType.ExecutionCompleted:
                historyEvent = new ExecutionCompletedEvent(
                    eventId,
                    result: GetPayloadText(reader),
                    orchestrationStatus: OrchestrationStatus.Completed);
                break;

            case EventType.ExecutionFailed:
                historyEvent = new ExecutionCompletedEvent(
                    eventId,
                    result: GetPayloadText(reader),
                    orchestrationStatus: OrchestrationStatus.Failed);
                break;

            case EventType.ExecutionStarted:
                historyEvent = new ExecutionStartedEvent(eventId, GetPayloadText(reader))
                {
                    Name = GetName(reader),
                    OrchestrationInstance = new OrchestrationInstance
                    {
                        InstanceId  = GetInstanceId(reader),
                        ExecutionId = GetExecutionId(reader),
                    },
                    Tags    = null,  // TODO
                    Version = GetVersion(reader),
                };
                string?parentInstanceId = GetParentInstanceId(reader);
                if (parentInstanceId != null)
                {
                    ((ExecutionStartedEvent)historyEvent).ParentInstance = new ParentInstance
                    {
                        OrchestrationInstance = new OrchestrationInstance
                        {
                            InstanceId = parentInstanceId
                        },
                        TaskScheduleId = GetTaskId(reader)
                    };
                }
                break;

            case EventType.ExecutionTerminated:
                historyEvent = new ExecutionTerminatedEvent(eventId, GetPayloadText(reader));
                break;

            case EventType.GenericEvent:
                historyEvent = new GenericEvent(eventId, GetPayloadText(reader));
                break;

            case EventType.OrchestratorCompleted:
                historyEvent = new OrchestratorCompletedEvent(eventId);
                break;

            case EventType.OrchestratorStarted:
                historyEvent = new OrchestratorStartedEvent(eventId);
                break;

            case EventType.SubOrchestrationInstanceCompleted:
                historyEvent = new SubOrchestrationInstanceCompletedEvent(eventId, GetTaskId(reader), GetPayloadText(reader));
                break;

            case EventType.SubOrchestrationInstanceCreated:
                historyEvent = new SubOrchestrationInstanceCreatedEvent(eventId)
                {
                    Input      = GetPayloadText(reader),
                    InstanceId = null,     // TODO
                    Name       = GetName(reader),
                    Version    = null,
                };
                break;

            case EventType.SubOrchestrationInstanceFailed:
                historyEvent = new SubOrchestrationInstanceFailedEvent(
                    eventId,
                    taskScheduledId: GetTaskId(reader),
                    reason: GetReason(reader),
                    details: GetPayloadText(reader));
                break;

            case EventType.TaskCompleted:
                historyEvent = new TaskCompletedEvent(
                    eventId,
                    taskScheduledId: GetTaskId(reader),
                    result: GetPayloadText(reader));
                break;

            case EventType.TaskFailed:
                historyEvent = new TaskFailedEvent(
                    eventId,
                    taskScheduledId: GetTaskId(reader),
                    reason: GetReason(reader),
                    details: GetPayloadText(reader));
                break;

            case EventType.TaskScheduled:
                historyEvent = new TaskScheduledEvent(eventId)
                {
                    Input   = GetPayloadText(reader),
                    Name    = GetName(reader),
                    Version = GetVersion(reader),
                };
                break;

            case EventType.TimerCreated:
                historyEvent = new TimerCreatedEvent(eventId)
                {
                    FireAt = GetVisibleTime(reader),
                };
                break;

            case EventType.TimerFired:
                historyEvent = new TimerFiredEvent(eventId)
                {
                    FireAt  = GetVisibleTime(reader),
                    TimerId = GetTaskId(reader),
                };
                break;

            default:
                throw new InvalidOperationException($"Don't know how to interpret '{eventType}'.");
            }

            historyEvent.Timestamp = GetTimestamp(reader);
            historyEvent.IsPlayed  = isOrchestrationHistory && (bool)reader["IsPlayed"];
            return(historyEvent);
        }