TaskMessage ProcessCreateTimerDecision( CreateTimerOrchestratorAction createTimerOrchestratorAction, OrchestrationRuntimeState runtimeState, bool isInternal) { var taskMessage = new TaskMessage(); var timerCreatedEvent = new TimerCreatedEvent(createTimerOrchestratorAction.Id) { FireAt = createTimerOrchestratorAction.FireAt }; runtimeState.AddEvent(timerCreatedEvent); taskMessage.Event = new TimerFiredEvent(-1) { TimerId = createTimerOrchestratorAction.Id, FireAt = createTimerOrchestratorAction.FireAt }; this.logHelper.CreatingTimer( runtimeState.OrchestrationInstance, timerCreatedEvent, isInternal); taskMessage.OrchestrationInstance = runtimeState.OrchestrationInstance; return(taskMessage); }
public void HandleTimerCreatedEvent(TimerCreatedEvent timerCreatedEvent) { int taskId = timerCreatedEvent.EventId; if (taskId == FrameworkConstants.FakeTimerIdToSplitDecision) { // This is our dummy timer to split decision for avoiding 100 messages per transaction service bus limit return; } if (!this.orchestratorActionsMap.ContainsKey(taskId)) { throw new NonDeterministicOrchestrationException(timerCreatedEvent.EventId, $"A previous execution of this orchestration scheduled a timer task with sequence number {taskId} but " + "the current replay execution hasn't (yet?) scheduled this task. Was a change made to the orchestrator " + "code after this instance had already started running?"); } var orchestrationAction = this.orchestratorActionsMap[taskId]; if (orchestrationAction is not CreateTimerOrchestratorAction) { throw new NonDeterministicOrchestrationException(timerCreatedEvent.EventId, $"A previous execution of this orchestration scheduled a timer task with sequence number {taskId} named " + $"but the current orchestration replay instead produced a {orchestrationAction.GetType().Name} action with " + "this sequence number. Was a change made to the orchestrator code after this instance had already " + "started running?"); } this.orchestratorActionsMap.Remove(taskId); }
/// <summary> /// Logs that an orchestration is creating a durable timer. /// </summary> /// <param name="instance">The orchestration instance scheduling the task activity.</param> /// <param name="timerEvent">The timer creation event.</param> /// <param name="isInternal"><c>true</c> if the timer was created internally by the framework; <c>false</c> if it was created by user code.</param> internal void CreatingTimer(OrchestrationInstance instance, TimerCreatedEvent timerEvent, bool isInternal) { if (this.IsStructuredLoggingEnabled) { this.WriteStructuredLog(new LogEvents.CreatingTimer(instance, timerEvent, isInternal)); } }
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); }
public void HandleTimerCreatedEvent(TimerCreatedEvent timerCreatedEvent) { int taskId = timerCreatedEvent.EventId; if (taskId == FrameworkConstants.FakeTimerIdToSplitDecision) { // This is our dummy timer to split decision for avoiding 100 messages per transaction service bus limit return; } if (this.orchestratorActionsMap.ContainsKey(taskId)) { this.orchestratorActionsMap.Remove(taskId); } else { throw new NonDeterministicOrchestrationException(timerCreatedEvent.EventId, $"TimerCreatedEvent: {timerCreatedEvent.EventId} {timerCreatedEvent.EventType}"); } }
public async Task <T> CreateTimer <T>(DateTime fireAt, T state, CancellationToken cancelToken) { var timerCreated = new TimerCreatedEvent(History.Count); History.Add(timerCreated); var timer = new OrchestrationTimer(fireAt, CurrentUtcDateTime, cancelToken); try { _activeTimers.Add(timer); await timer.Wait(); History.Add(new TimerFiredEvent(timerCreated.EventId)); } finally { _activeTimers.Remove(timer); } return(state); }
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); }