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