public void WaitAll_OutputsNothing_WhenAnyTaskIsNotCompleted( bool scheduled, bool completed) { var history = DurableTestUtilities.MergeHistories( CreateActivityHistory("FunctionA", scheduled: true, completed: true, output: "\"Result1\""), // completed CreateActivityHistory("FunctionA", scheduled: true, completed: true, output: "\"Result2\""), CreateDurableTimerHistory(timerCreated: scheduled, timerFired: completed, fireAt: _fireAt, _restartTime, orchestratorStartedIsProcessed: false), CreateActivityHistory("FunctionB", scheduled: true, completed: true, output: "\"Result3\"") // completed ); var orchestrationContext = new OrchestrationContext { History = history }; var tasksToWaitFor = new ReadOnlyCollection <DurableTask>( new DurableTask[] { new ActivityInvocationTask("FunctionA", FunctionInput), new ActivityInvocationTask("FunctionA", FunctionInput), new DurableTimerTask(_fireAt), new ActivityInvocationTask("FunctionB", FunctionInput) }); var durableTaskHandler = new DurableTaskHandler(); DurableTestUtilities.EmulateStop(durableTaskHandler); durableTaskHandler.WaitAll(tasksToWaitFor, orchestrationContext, _ => { Assert.True(false, "Unexpected output"); }); VerifyNoOrchestrationActionAdded(orchestrationContext); }
public void WaitAll_WaitsForStop_WhenAnyTaskIsNotCompleted(bool scheduledAndCompleted, bool expectedWaitForStop) { var history = DurableTestUtilities.MergeHistories( CreateActivityHistory("FunctionA", scheduled: true, completed: true, output: "\"Result1\""), CreateActivityHistory("FunctionA", scheduled: scheduledAndCompleted, completed: scheduledAndCompleted, output: "\"Result2\""), CreateDurableTimerHistory(timerCreated: scheduledAndCompleted, timerFired: scheduledAndCompleted, fireAt: _fireAt, _restartTime, orchestratorStartedIsProcessed: false), CreateActivityHistory("FunctionB", scheduled: true, completed: true, output: "\"Result3\"") ); var durableTaskHandler = new DurableTaskHandler(); var orchestrationContext = new OrchestrationContext { History = history }; var tasksToWaitFor = new ReadOnlyCollection <DurableTask>( new DurableTask[] { new ActivityInvocationTask("FunctionA", FunctionInput), new ActivityInvocationTask("FunctionA", FunctionInput), new DurableTimerTask(_fireAt), new ActivityInvocationTask("FunctionB", FunctionInput) }); DurableTestUtilities.VerifyWaitForDurableTasks( durableTaskHandler, _delayBeforeStopping, expectedWaitForStop, () => { durableTaskHandler.WaitAll(tasksToWaitFor, orchestrationContext, _ => { }); }); }
protected override void EndProcessing() { var privateData = (Hashtable)MyInvocation.MyCommand.Module.PrivateData; var context = (OrchestrationContext)privateData[SetFunctionInvocationContextCommand.ContextKey]; if (Any.IsPresent) { _durableTaskHandler.WaitAny(Task, context, WriteObject); } else { _durableTaskHandler.WaitAll(Task, context, WriteObject); } }
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 WaitAll_OutputsTaskResults_WhenAllTasksCompleted( bool scheduled, bool completed) { var history = DurableTestUtilities.MergeHistories( // Emulate invoking the same function (FunctionA) twice. This is to make sure that // both invocations are accounted for, and both results are preserved separately. // Without this test, the history lookup algorithm in the WaitForActivityTasks method // could just look for the the first history event by function name, and this error // would not be detected. CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true), CreateActivityHistory("FunctionA", scheduled: scheduled, completed: completed, output: "\"Result1\""), CreateActivityHistory("FunctionA", scheduled: scheduled, completed: completed, output: "\"Result2\""), CreateDurableTimerHistory(timerCreated: scheduled, timerFired: completed, fireAt: _fireAt, _restartTime, orchestratorStartedIsProcessed: false), CreateActivityHistory("FunctionB", scheduled: scheduled, completed: completed, output: "\"Result3\"") ); var orchestrationContext = new OrchestrationContext { History = history }; var tasksToWaitFor = new ReadOnlyCollection <DurableTask>( new DurableTask[] { new ActivityInvocationTask("FunctionA", FunctionInput), new ActivityInvocationTask("FunctionA", FunctionInput), new DurableTimerTask(_fireAt), new ActivityInvocationTask("FunctionB", FunctionInput) }); var allOutput = new List <object>(); var durableTaskHandler = new DurableTaskHandler(); durableTaskHandler.WaitAll(tasksToWaitFor, orchestrationContext, output => { allOutput.Add(output); }); Assert.Equal(new[] { "Result1", "Result2", "Result3" }, allOutput); VerifyNoOrchestrationActionAdded(orchestrationContext); }
// Verifies that CurrentUtcDateTime updates to the next OrchestratorStarted event (not a later OrchestratorStartedEvent) if all activity functions complete // If any activity is not complete, CurrentUtcDateTime does not update // This test assumes that when all activities are completed, TaskScheduled events -> OrchestratorStarted event -> TaskCompleted events are added to history in that order // Otherwise, only TaskScheduled events are added to the history public void CurrentUtcDateTime_UpdatesToNextOrchestratorStartedTimestamp_IfAllActivitiesCompleted_WhenWaitAllIsCalled(bool allCompleted) { var activityFunctions = new Dictionary <string, bool>(); activityFunctions.Add("FunctionA", true); activityFunctions.Add("FunctionB", allCompleted); activityFunctions.Add("FunctionC", true); var history = DurableTestUtilities.MergeHistories( CreateOrchestratorStartedHistory(startTime: _startTime, isProcessed: true), CreateNoWaitActivityHistory(scheduled: activityFunctions, restartTime: _restartTime, orchestratorStartedIsProcessed: false), CreateOrchestratorStartedHistory(startTime: _shouldNotHitTime, isProcessed: false) ); OrchestrationContext context = new OrchestrationContext { History = history, CurrentUtcDateTime = _startTime }; var tasksToWaitFor = new ReadOnlyCollection <ActivityInvocationTask>( new[] { "FunctionA", "FunctionB", "FunctionC" }.Select(name => new ActivityInvocationTask(name, FunctionInput)).ToArray()); var durableTaskHandler = new DurableTaskHandler(); var allOutput = new List <object>(); if (!allCompleted) { DurableTestUtilities.EmulateStop(durableTaskHandler); } durableTaskHandler.WaitAll(tasksToWaitFor, context, output => allOutput.Add(output)); if (allCompleted) { Assert.Equal(_restartTime, context.CurrentUtcDateTime); } else { Assert.Equal(_startTime, context.CurrentUtcDateTime); } }