Пример #1
0
        public void TestFromFailToNotAllowedTransitions()
        {
            var taskState = new TaskStateMachine();

            taskState.MoveNext(TaskStateEvent.SubmittedTask);
            taskState.MoveNext(TaskStateEvent.RunningTask);

            taskState.MoveNext(TaskStateEvent.FailedTaskEvaluatorError);
            Assert.True(taskState.CurrentState.Equals(TaskState.TaskFailedByEvaluatorFailure), "Failed to move to TaskFailedByEvaluatorFailure state.");

            Action moveNext = () => taskState.MoveNext(TaskStateEvent.RunningTask);

            Assert.Throws <TaskStateTransitionException>(moveNext);

            moveNext = () => taskState.MoveNext(TaskStateEvent.ClosedTask);
            Assert.Throws <TaskStateTransitionException>(moveNext);

            moveNext = () => taskState.MoveNext(TaskStateEvent.CompletedTask);
            Assert.Throws <TaskStateTransitionException>(moveNext);

            moveNext = () => taskState.MoveNext(TaskStateEvent.SubmittedTask);
            Assert.Throws <TaskStateTransitionException>(moveNext);

            moveNext = () => taskState.MoveNext(TaskStateEvent.WaitingTaskToClose);
            Assert.Throws <TaskStateTransitionException>(moveNext);

            moveNext = () => taskState.MoveNext(TaskStateEvent.FailedTaskAppError);
            Assert.Throws <TaskStateTransitionException>(moveNext);

            moveNext = () => taskState.MoveNext(TaskStateEvent.FailedTaskCommunicationError);
            Assert.Throws <TaskStateTransitionException>(moveNext);

            moveNext = () => taskState.MoveNext(TaskStateEvent.FailedTaskSystemError);
            Assert.Throws <TaskStateTransitionException>(moveNext);
        }
Пример #2
0
 /// <summary>
 /// Construct a TaskInfo that wraps task state, task configuration, and active context for submitting the task
 /// </summary>
 /// <param name="taskState"></param>
 /// <param name="config"></param>
 /// <param name="context"></param>
 internal TaskInfo(TaskStateMachine taskState, IConfiguration config, IActiveContext context)
 {
     _taskState         = taskState;
     _taskConfiguration = config;
     _activeContext     = context;
     TimeStateUpdated   = DateTime.Now;
 }
Пример #3
0
        public void TestRunningToCloseToFailedTaskSystemErrorScenario()
        {
            var taskState = new TaskStateMachine();

            taskState.MoveNext(TaskStateEvent.SubmittedTask);
            taskState.MoveNext(TaskStateEvent.RunningTask);
            taskState.MoveNext(TaskStateEvent.WaitingTaskToClose);
            Assert.True(taskState.MoveNext(TaskStateEvent.FailedTaskSystemError).Equals(TaskState.TaskClosedByDriver), "Failed to move from WaitingTaskToClose to TaskClosedByDriver state with FailedTaskSystemError.");
        }
Пример #4
0
        public void TestRunningToFailByEvaluatorScenario()
        {
            var taskState = new TaskStateMachine();

            taskState.MoveNext(TaskStateEvent.SubmittedTask);
            taskState.MoveNext(TaskStateEvent.RunningTask);
            Assert.True(taskState.MoveNext(TaskStateEvent.FailedTaskEvaluatorError).Equals(TaskState.TaskFailedByEvaluatorFailure), "Failed to move from RunningTask to TaskFailedByEvaluatorFailure state with FailedTaskEvaluatorError.");
            Assert.True(taskState.IsFinalState(), "TaskFailedByEvaluatorFailure should be a final state.");
        }
Пример #5
0
        public void TestRunningToWaitingTaskToCloseToComplete()
        {
            var taskState = new TaskStateMachine();

            taskState.MoveNext(TaskStateEvent.SubmittedTask);
            taskState.MoveNext(TaskStateEvent.RunningTask);
            taskState.MoveNext(TaskStateEvent.WaitingTaskToClose);
            taskState.MoveNext(TaskStateEvent.CompletedTask);
            Assert.Equal(TaskState.TaskClosedByDriver, taskState.CurrentState);
        }
Пример #6
0
        public void TestRunningToCloseScenario()
        {
            var taskState = new TaskStateMachine();

            taskState.MoveNext(TaskStateEvent.SubmittedTask);
            taskState.MoveNext(TaskStateEvent.RunningTask);
            Assert.True(taskState.MoveNext(TaskStateEvent.WaitingTaskToClose).Equals(TaskState.TaskWaitingForClose), "Failed to move from RunningTask to TaskWaitingForClose state.");
            Assert.False(taskState.IsFinalState(), "TaskWaitingForClose should not be a final state.");
            Assert.True(taskState.MoveNext(TaskStateEvent.ClosedTask).Equals(TaskState.TaskClosedByDriver), "Failed to move from TaskWaitingForClose to TaskClosedByDriver state.");
            Assert.True(taskState.IsFinalState(), "TaskClosedByDriver should be a final state.");
        }
Пример #7
0
        public void TestNewToCompleteScenario()
        {
            var taskState = new TaskStateMachine();

            Assert.True(taskState.CurrentState.Equals(TaskState.TaskNew), "State of newly created task should be TaskNew");
            Assert.False(taskState.IsFinalState(), "TaskNew should not be a final state.");
            Assert.True(taskState.MoveNext(TaskStateEvent.SubmittedTask).Equals(TaskState.TaskSubmitted), "Failed to move from TaskNew to TaskSubmitted state.");
            Assert.False(taskState.IsFinalState(), "TaskSubmitted should not be a final state.");
            Assert.True(taskState.MoveNext(TaskStateEvent.RunningTask).Equals(TaskState.TaskRunning), "Failed to move from TaskSubmitted to TaskRunning state.");
            Assert.False(taskState.IsFinalState(), "TaskRunning should not be a final state.");
            Assert.True(taskState.MoveNext(TaskStateEvent.CompletedTask).Equals(TaskState.TaskCompleted), "Failed to move from TaskRunning to TaskCompleted state.");
            Assert.True(taskState.IsFinalState(), "TaskCompleted should be a final state.");
        }
Пример #8
0
        public void TestFromRunningToNotAllowedTransitions()
        {
            var taskState = new TaskStateMachine();

            taskState.MoveNext(TaskStateEvent.SubmittedTask);
            taskState.MoveNext(TaskStateEvent.RunningTask);

            Action moveNext = () => taskState.MoveNext(TaskStateEvent.SubmittedTask);

            Assert.Throws <TaskStateTransitionException>(moveNext);

            moveNext = () => taskState.MoveNext(TaskStateEvent.ClosedTask);
            Assert.Throws <TaskStateTransitionException>(moveNext);
        }
Пример #9
0
        public static Task MainCompiled(string[] args)
        {
            var taskMethodBuilder = AsyncTaskMethodBuilder.Create();

            TaskStateMachine stateMachine = new TaskStateMachine();

            stateMachine.args        = args;
            stateMachine.taskBuilder = taskMethodBuilder;
            stateMachine.state       = -1;

            taskMethodBuilder.Start(ref stateMachine);

            return(stateMachine.taskBuilder.Task);
        }
Пример #10
0
            // This is the section where actual logic of original method exist
            // Contain the logic to execute the code till await statement
            // Also configure stuff of the wake up call when async method complete it's execution
            public void MoveNext()
            {
                // Set state to local variable for performance
                int num = state;

                try
                {
                    // Variables to save awaiters for the new tasks
                    TaskAwaiter        firstAwaiter;
                    TaskAwaiter <bool> secondAwaiter;

                    // Initially -1
                    if (num != 0)
                    {
                        if (num == 1)
                        {
                            // We get the awaiter from the execution context again
                            secondAwaiter = SecondAwaiter;

                            // Set to null to release memory allocation
                            SecondAwaiter = default;

                            // Restart the state as we are about to finish
                            num = (state = -1);

                            // Don't use goto unless you know what you are doing! :)
                            goto IL_0114;
                        }

                        // Execute first task with its context
                        inputContext       = new InputContext();
                        inputContext.input = 5;
                        firstAwaiter       = Task.Run(inputContext.ConsoleWriteLine).GetAwaiter();

                        // This block is for optimization in case the task is already finished (Task.FromResult)
                        // Most probably - this block will be executed
                        if (!firstAwaiter.IsCompleted)
                        {
                            num = (state = 0);
                            // Save the awaiter for the next state.
                            FirstAwaiter = firstAwaiter;
                            TaskStateMachine stateMachine = this;

                            // This call to AwaitUnsafeOnCompleted is where most of the magic happens
                            // In this step we register the StateMachine as continuation of the task by calling AwaitUnsafeOnCompleted
                            // But how it is done?
                            // builder.AwaitUnsafeOnCompleted do multiple things in background
                            // 1. TaskMethodBuilder captures Execution context
                            // 2. Create an MoveNextAction using Execution context
                            // 3. This MoveNextAction will call the MoveNext of state machine and provide execution context
                            // 4. Set MoveNextAction as callback to awaiter on complete Using awaiter.UnsafeOnCompleted(action)
                            taskBuilder.AwaitUnsafeOnCompleted(ref firstAwaiter, ref stateMachine);
                            return;
                        }
                    }
                    else
                    {
                        // Second time - we get the awaiter from the execution context
                        firstAwaiter = FirstAwaiter;

                        // Set to null to release memory allocation
                        FirstAwaiter = default;
                        num          = (state = -1);
                    }

                    firstAwaiter.GetResult();

                    // Execute second task with its context
                    secondAwaiter = Task
                                    .Run(ReturnContext.FunctionCall ?? (ReturnContext.FunctionCall = ReturnContext.Context.ReturnTrue))
                                    .GetAwaiter();

                    // Again - for optimization
                    if (!secondAwaiter.IsCompleted)
                    {
                        num = (state = 1);
                        // Save the awaiter for the next state.
                        SecondAwaiter = secondAwaiter;
                        TaskStateMachine stateMachine = this;
                        // Register the state machine to continue with the next state
                        taskBuilder.AwaitUnsafeOnCompleted(ref secondAwaiter, ref stateMachine);
                        return;
                    }

IL_0114:
                    // Finish by getting the awaiter result and execute the logic
                    result = secondAwaiter.GetResult();
                    Console.WriteLine(result);
                }
                catch (Exception exception)
                {
                    // Exception handling mechanism
                    state = -2;
                    taskBuilder.SetException(exception);
                    return;
                }

                // Set the state to final state we are done
                state = -2;

                // Set the result on the task builder
                taskBuilder.SetResult();
            }
Пример #11
0
 /// <summary>
 /// Construct a TaskInfo that wraps task state, task configuration, and active context for submitting the task
 /// </summary>
 /// <param name="taskState"></param>
 /// <param name="config"></param>
 /// <param name="context"></param>
 internal TaskInfo(TaskStateMachine taskState, IConfiguration config, IActiveContext context)
 {
     _taskState         = taskState;
     _taskConfiguration = config;
     _activeContext     = context;
 }