public void StopAndInitiateDurableTaskOrReplay_UpdatesCurrentUtcDateTimeToNextOrchestratorStartedTimestamp_OnlyIfTimerCreatedAndFired(bool timerCreated, bool timerFired) { var history = DurableTestUtilities.MergeHistories( CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true), CreateDurableTimerHistory(timerCreated: timerCreated, timerFired: timerFired, fireAt: _fireAt, restartTime: _restartTime, orchestratorStartedIsProcessed: false), CreateOrchestratorStartedHistory(date: _shouldNotHitTime, isProcessed: false) ); var context = new OrchestrationContext { History = history, CurrentUtcDateTime = _startTime }; var durableTaskHandler = new DurableTaskHandler(); var task = new DurableTimerTask(_fireAt); if (!timerCreated || !timerFired) { DurableTestUtilities.EmulateStop(durableTaskHandler); durableTaskHandler.StopAndInitiateDurableTaskOrReplay( task: task, context: context, noWait: false, output: _ => { Assert.True(false, "Unexpected output"); }, onFailure: _ => { }); Assert.Equal(_startTime, context.CurrentUtcDateTime); } else { durableTaskHandler.StopAndInitiateDurableTaskOrReplay(task: task, context: context, noWait: false, _ => { Assert.True(false, "Unexpected output"); }, errorMessage => { }); Assert.Equal(_restartTime, context.CurrentUtcDateTime); } VerifyCreateDurableTimerActionAdded(context, _fireAt); }
public void StopAndInitiateDurableTaskOrReplay_ContinuesToNextTimer_IfTimersHaveIdenticalFireAt() { var history = DurableTestUtilities.MergeHistories( CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true), CreateDurableTimerHistory(timerCreated: true, timerFired: true, fireAt: _fireAt, restartTime: _restartTime, orchestratorStartedIsProcessed: false), CreateDurableTimerHistory(timerCreated: true, timerFired: true, fireAt: _fireAt, restartTime: _restartTime, orchestratorStartedIsProcessed: false), CreateDurableTimerHistory(timerCreated: true, timerFired: true, fireAt: _fireAt, restartTime: _shouldNotHitTime, orchestratorStartedIsProcessed: false) ); var context = new OrchestrationContext { History = history }; var durableTaskHandler = new DurableTaskHandler(); for (int i = 0; i < 2; i++) { durableTaskHandler.StopAndInitiateDurableTaskOrReplay( task: new DurableTimerTask(_fireAt), context: context, noWait: false, output: _ => { Assert.True(false, "Unexpected output"); }, onFailure: _ => { }); Assert.Equal(_restartTime, context.CurrentUtcDateTime); } durableTaskHandler.StopAndInitiateDurableTaskOrReplay( task: new DurableTimerTask(_fireAt), context: context, noWait: false, output: _ => { Assert.True(false, "Unexpected output"); }, onFailure: _ => { }); Assert.Equal(_shouldNotHitTime, context.CurrentUtcDateTime); }
public void StopAndInitiateDurableTaskOrReplay_ReplaysMultipleActivitiesWithTheSameName() { var loadedFunctions = new[] { DurableTestUtilities.CreateFakeActivityTriggerAzFunctionInfo("FunctionA"), DurableTestUtilities.CreateFakeActivityTriggerAzFunctionInfo("FunctionB") }; var history = DurableTestUtilities.MergeHistories( CreateHistory("FunctionA", scheduled: true, completed: true, output: "\"Result1\""), CreateHistory("FunctionB", scheduled: true, completed: true, output: "\"Result2\""), CreateHistory("FunctionA", scheduled: true, completed: true, output: "\"Result3\"") ); var orchestrationContext = new OrchestrationContext { History = history }; var allOutput = new List <object>(); var durableTaskHandler = new DurableTaskHandler(); // Replay FunctionA only for (var i = 0; i < 2; ++i) { durableTaskHandler.StopAndInitiateDurableTaskOrReplay( new ActivityInvocationTask("FunctionA", FunctionInput), orchestrationContext, noWait: false, output => { allOutput.Add(output); }); } // Expect FunctionA results only Assert.Equal(new[] { "Result1", "Result3" }, allOutput); }
protected override void EndProcessing() { var privateData = (Hashtable)MyInvocation.MyCommand.Module.PrivateData; var context = (OrchestrationContext)privateData[SetFunctionInvocationContextCommand.ContextKey]; var task = new ExternalEventTask(EventName); _durableTaskHandler.StopAndInitiateDurableTaskOrReplay( task, context, NoWait.IsPresent, WriteObject, failureReason => DurableActivityErrorHandler.Handle(this, failureReason)); }
protected override void EndProcessing() { var privateData = (Hashtable)MyInvocation.MyCommand.Module.PrivateData; var context = (OrchestrationContext)privateData[SetFunctionInvocationContextCommand.ContextKey]; DateTime fireAt = context.CurrentUtcDateTime.Add(Duration); var task = new DurableTimerTask(fireAt); _durableTaskHandler.StopAndInitiateDurableTaskOrReplay( task, context, NoWait.IsPresent, WriteObject, failureReason => DurableActivityErrorHandler.Handle(this, failureReason)); }
public void StopAndInitiateDurableTaskOrReplay_RetriesOnFailure() { const string FunctionName = "Function"; const string FunctionInput = "Input"; var history = new[] { new HistoryEvent { EventType = HistoryEventType.TaskScheduled, Name = FunctionName, EventId = 1 }, new HistoryEvent { EventType = HistoryEventType.TaskFailed, TaskScheduledId = 1 }, new HistoryEvent { EventType = HistoryEventType.TimerCreated, EventId = 2 }, new HistoryEvent { EventType = HistoryEventType.TimerFired, TimerId = 2 }, new HistoryEvent { EventType = HistoryEventType.TaskScheduled, Name = FunctionName, EventId = 3 }, new HistoryEvent { EventType = HistoryEventType.TaskCompleted, Result = "\"OK\"", TaskScheduledId = 3 }, }; var orchestrationContext = new OrchestrationContext { History = history }; var durableTaskHandler = new DurableTaskHandler(); var retryOptions = new RetryOptions(TimeSpan.FromSeconds(1), 2, null, null, null); object result = null; durableTaskHandler.StopAndInitiateDurableTaskOrReplay( new ActivityInvocationTask(FunctionName, FunctionInput, retryOptions), orchestrationContext, noWait: false, output: output => { result = output; }, onFailure: _ => { Assert.True(false, "Unexpected failure"); }, retryOptions: retryOptions ); Assert.Equal("OK", result); var(_, actions) = orchestrationContext.OrchestrationActionCollector.WaitForActions(new AutoResetEvent(initialState: true)); var action = (CallActivityWithRetryAction)actions.Single().Single(); Assert.Equal(FunctionName, action.FunctionName); Assert.Equal(FunctionInput, action.Input); Assert.NotEmpty(action.RetryOptions); }
public void WaitAll_And_WaitAny_StartNewActivityBatch(bool invokeWaitAll, bool invokeWaitAny, int expectedNumberOfBatches) { var orchestrationContext = new OrchestrationContext { History = new HistoryEvent[0] }; var durableTaskHandler = new DurableTaskHandler(); durableTaskHandler.StopAndInitiateDurableTaskOrReplay( new ActivityInvocationTask("Function", "Input"), orchestrationContext, noWait: true, output: _ => {}, onFailure: _ => {} ); if (invokeWaitAll) { durableTaskHandler.Stop(); // just to avoid the next call getting stuck waiting for a stop event durableTaskHandler.WaitAll(new DurableTask[0], orchestrationContext, output: _ => {}); } if (invokeWaitAny) { durableTaskHandler.Stop(); // just to avoid the next call getting stuck waiting for a stop event durableTaskHandler.WaitAny(new DurableTask[0], orchestrationContext, output: _ => {}); } durableTaskHandler.StopAndInitiateDurableTaskOrReplay( new ActivityInvocationTask("Function", "Input"), orchestrationContext, noWait: true, output: _ => {}, onFailure: _ => {} ); var(_, actions) = orchestrationContext.OrchestrationActionCollector.WaitForActions(new AutoResetEvent(initialState: true)); Assert.Equal(expectedNumberOfBatches, actions.Count); }
public void StopAndInitiateDurableTaskOrReplay_OutputsDurableTimerTask_IfNoWaitRequested() { var history = CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true); var context = new OrchestrationContext { History = history }; var allOutput = new List <DurableTimerTask>(); var durableTaskHandler = new DurableTaskHandler(); durableTaskHandler.StopAndInitiateDurableTaskOrReplay(task: new DurableTimerTask(_fireAt), context: context, noWait: true, output => { allOutput.Add((DurableTimerTask)output); }); Assert.Equal(_fireAt, allOutput.Single().FireAt); VerifyCreateDurableTimerActionAdded(context, _fireAt); }
protected override void EndProcessing() { var privateData = (Hashtable)MyInvocation.MyCommand.Module.PrivateData; var context = (OrchestrationContext)privateData[SetFunctionInvocationContextCommand.ContextKey]; var loadedFunctions = FunctionLoader.GetLoadedFunctions(); var task = new ActivityInvocationTask(FunctionName, Input, RetryOptions); ActivityInvocationTask.ValidateTask(task, loadedFunctions); _durableTaskHandler.StopAndInitiateDurableTaskOrReplay( task, context, NoWait.IsPresent, output: WriteObject, onFailure: failureReason => DurableActivityErrorHandler.Handle(this, failureReason), retryOptions: RetryOptions); }
public void CurrentUtcDateTime_UpdatesToNextOrchestratorStartedTimestamp_IfActivityFunctionCompleted(bool completed) { var history = DurableTestUtilities.MergeHistories( CreateOrchestratorStartedHistory(startTime: _startTime, isProcessed: true), CreateActivityHistory( name: FunctionName, scheduled: true, completed: completed, output: InvocationResultJson, date: _restartTime, orchestratorStartedIsProcessed: false) ); OrchestrationContext context = new OrchestrationContext { History = history, CurrentUtcDateTime = _startTime }; var durableTaskHandler = new DurableTaskHandler(); var allOutput = new List <object>(); if (completed) { history = DurableTestUtilities.MergeHistories(history, CreateActivityHistory( name: FunctionName, scheduled: true, completed: true, output: InvocationResultJson, date: _shouldNotHitTime, orchestratorStartedIsProcessed: false)); } else { DurableTestUtilities.EmulateStop(durableTaskHandler); } durableTaskHandler.StopAndInitiateDurableTaskOrReplay( new ActivityInvocationTask(FunctionName, FunctionInput), context, noWait: false, output: output => allOutput.Add(output), onFailure: _ => { }); if (completed) { Assert.Equal(_restartTime, context.CurrentUtcDateTime); } else { Assert.Equal(_startTime, context.CurrentUtcDateTime); } }
public void CurrentUtcDateTime_UpdatesToNextOrchestratorStartedTimestamp_IfTimestampsAreIdentical() { var history = DurableTestUtilities.MergeHistories( CreateActivityHistory( name: FunctionName, scheduled: true, completed: true, date: _startTime, output: InvocationResultJson, orchestratorStartedIsProcessed: true), CreateActivityHistory( name: FunctionName, scheduled: true, completed: true, date: _startTime, output: InvocationResultJson, orchestratorStartedIsProcessed: false), CreateActivityHistory( name: FunctionName, scheduled: true, completed: true, date: _shouldNotHitTime, output: InvocationResultJson, orchestratorStartedIsProcessed: false) ); var context = new OrchestrationContext { History = history, CurrentUtcDateTime = _startTime }; var willHitEvent = context.History.First( e => e.EventType == HistoryEventType.OrchestratorStarted && e.IsProcessed); var allOutput = new List <object>(); var durableTaskHandler = new DurableTaskHandler(); durableTaskHandler.StopAndInitiateDurableTaskOrReplay( new ActivityInvocationTask(FunctionName, FunctionInput), context, noWait: false, output: output => allOutput.Add(output), onFailure: _ => { }); Assert.Equal(_startTime, context.CurrentUtcDateTime); var shouldNotHitEvent = context.History.First( e => e.Timestamp.Equals(_shouldNotHitTime)); Assert.True(willHitEvent.IsProcessed); Assert.False(shouldNotHitEvent.IsProcessed); }
public void StopAndInitiateDurableTaskOrReplay_OutputsNothing_IfActivityNotCompleted( bool scheduled, bool completed) { var history = CreateHistory(scheduled: scheduled, completed: completed, output: InvocationResultJson); var orchestrationContext = new OrchestrationContext { History = history }; var durableTaskHandler = new DurableTaskHandler(); DurableTestUtilities.EmulateStop(durableTaskHandler); durableTaskHandler.StopAndInitiateDurableTaskOrReplay( new ActivityInvocationTask(FunctionName, FunctionInput), orchestrationContext, noWait: false, _ => { Assert.True(false, "Unexpected output"); }); VerifyCallActivityActionAdded(orchestrationContext); }
public void StopAndInitiateDurableTaskOrReplay_ReplaysActivity_IfActivityCompleted( bool scheduled, bool completed) { var history = CreateHistory(scheduled: scheduled, completed: completed, output: InvocationResultJson); var orchestrationContext = new OrchestrationContext { History = history }; var allOutput = new List <object>(); var durableTaskHandler = new DurableTaskHandler(); durableTaskHandler.StopAndInitiateDurableTaskOrReplay( task: new ActivityInvocationTask(FunctionName, FunctionInput), orchestrationContext, noWait: false, output => { allOutput.Add(output); }); VerifyCallActivityActionAdded(orchestrationContext); Assert.Equal(InvocationResult, allOutput.Single()); }
public void StopAndInitiateDurableTaskOrReplay_OutputsActivityInvocationTask_WhenNoWaitRequested( bool scheduled, bool completed) { var history = CreateHistory(scheduled: scheduled, completed: completed, output: InvocationResultJson); var orchestrationContext = new OrchestrationContext { History = history }; var allOutput = new List <ActivityInvocationTask>(); var durableTaskHandler = new DurableTaskHandler(); durableTaskHandler.StopAndInitiateDurableTaskOrReplay( new ActivityInvocationTask(FunctionName, FunctionInput), orchestrationContext, noWait: true, output => { allOutput.Add((ActivityInvocationTask)output); }); VerifyCallActivityActionAdded(orchestrationContext); Assert.Equal(FunctionName, allOutput.Single().FunctionName); }
public void StopAndInitiateDurableTaskOrReplay_OutputsError_IfActivityFailed() { const string FailureReason = "Failure reason"; var history = CreateHistory(scheduled: true, completed: false, failed: true, output: InvocationResultJson, failureReason: FailureReason); var orchestrationContext = new OrchestrationContext { History = history }; var allErrors = new List <object>(); var durableTaskHandler = new DurableTaskHandler(); durableTaskHandler.StopAndInitiateDurableTaskOrReplay( task: new ActivityInvocationTask(FunctionName, FunctionInput), orchestrationContext, noWait: false, output: _ => { Assert.True(false, "Unexpected output"); }, onFailure: reason => { allErrors.Add(reason); }); VerifyCallActivityActionAdded(orchestrationContext); Assert.Equal(FailureReason, allErrors.Single()); }
public void StopAndInitiateDurableTaskOrReplay_OutputsNothing_IfNoWaitNotRequested(bool timerCreated, bool timerFired) { var history = DurableTestUtilities.MergeHistories( CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true), CreateDurableTimerHistory(timerCreated: timerCreated, timerFired: timerFired, fireAt: _fireAt, restartTime: _restartTime, orchestratorStartedIsProcessed: false) ); var context = new OrchestrationContext { History = history }; var durableTaskHandler = new DurableTaskHandler(); if (!timerCreated || !timerFired) { DurableTestUtilities.EmulateStop(durableTaskHandler); } durableTaskHandler.StopAndInitiateDurableTaskOrReplay(task: new DurableTimerTask(_fireAt), context: context, noWait: false, _ => { Assert.True(false, "Unexpected output"); }); VerifyCreateDurableTimerActionAdded(context, _fireAt); }
public void StopAndCreateTimerOrContinue_WaitsUntilTimerFires_IfNoWaitNotRequested(bool timerCreated, bool timerFired, bool expectedWaitForStop) { var history = DurableTestUtilities.MergeHistories( CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true), CreateDurableTimerHistory(timerCreated: timerCreated, timerFired: timerFired, fireAt: _fireAt, restartTime: _restartTime, orchestratorStartedIsProcessed: false) ); var context = new OrchestrationContext { History = history, CurrentUtcDateTime = _startTime }; var durableTaskHandler = new DurableTaskHandler(); DurableTestUtilities.VerifyWaitForDurableTasks( durableTaskHandler, delayBeforeStopping: _longInterval, expectedWaitForStop: expectedWaitForStop, () => { durableTaskHandler.StopAndInitiateDurableTaskOrReplay(task: new DurableTimerTask(_fireAt), context: context, noWait: false, _ => { Assert.True(false, "Unexpected output"); }); }); }
public void StopAndInitiateDurableTaskOrReplay_WaitsForStop_IfActivityNotCompleted(bool scheduledAndCompleted, bool expectedWaitForStop) { var durableTaskHandler = new DurableTaskHandler(); var history = CreateHistory( scheduled: scheduledAndCompleted, completed: scheduledAndCompleted, output: InvocationResultJson); var orchestrationContext = new OrchestrationContext { History = history }; DurableTestUtilities.VerifyWaitForDurableTasks( durableTaskHandler, _delayBeforeStopping, expectedWaitForStop, () => { durableTaskHandler.StopAndInitiateDurableTaskOrReplay( new ActivityInvocationTask(FunctionName, FunctionInput), orchestrationContext, noWait: false, _ => { }); }); }
public void StopAndInitiateDurableTaskOrReplay_AddsActivityBatch_UnlessNoWait(bool noWait, int numberOfActions, int expectedNumberOfBatches) { var orchestrationContext = new OrchestrationContext { History = new HistoryEvent[0] }; var durableTaskHandler = new DurableTaskHandler(); for (var i = 0; i < numberOfActions; ++i) { durableTaskHandler.Stop(); // just to avoid the next call getting stuck waiting for a stop event durableTaskHandler.StopAndInitiateDurableTaskOrReplay( new ActivityInvocationTask("Function", "Input"), orchestrationContext, noWait: noWait, output: _ => {}, onFailure: _ => {} ); } var(_, actions) = orchestrationContext.OrchestrationActionCollector.WaitForActions(new AutoResetEvent(initialState: true)); Assert.Equal(expectedNumberOfBatches, actions.Count); }