Repository: reef
Updated Branches:
  refs/heads/master bdd6cbf0e -> 2ee2ca980


[REEF-1327] Creating task states and task state transitions

Adding TaskStateMachine, TaskState and TaskStateEvent
Adding tests for task states transitions

JIRA:
  [REEF-1327](https://issues.apache.org/jira/browse/REEF-1327)

Pull Request:
  This closes #963


Project: http://git-wip-us.apache.org/repos/asf/reef/repo
Commit: http://git-wip-us.apache.org/repos/asf/reef/commit/2ee2ca98
Tree: http://git-wip-us.apache.org/repos/asf/reef/tree/2ee2ca98
Diff: http://git-wip-us.apache.org/repos/asf/reef/diff/2ee2ca98

Branch: refs/heads/master
Commit: 2ee2ca98026a7bbcc171aaab9deabaf148e0260d
Parents: bdd6cbf
Author: Julia Wang <[email protected]>
Authored: Thu Apr 21 20:27:57 2016 -0700
Committer: Markus Weimer <[email protected]>
Committed: Tue Apr 26 09:21:52 2016 -0700

----------------------------------------------------------------------
 .../Org.Apache.REEF.IMRU.Tests.csproj           |   1 +
 .../TestTaskStates.cs                           | 251 +++++++++++++++++++
 .../OnREEF/Driver/IMRUSystemException.cs        |   2 +-
 .../Driver/StateMachine/SystemStateMachine.cs   |   2 +-
 .../SystemStateTransitionException.cs           |   3 +-
 .../OnREEF/Driver/StateMachine/TaskState.cs     |  75 ++++++
 .../Driver/StateMachine/TaskStateEvent.cs       |  70 ++++++
 .../Driver/StateMachine/TaskStateMachine.cs     | 145 +++++++++++
 .../TaskStateTransitionException.cs             |  48 ++++
 .../Org.Apache.REEF.IMRU.csproj                 |   4 +
 10 files changed, 597 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/reef/blob/2ee2ca98/lang/cs/Org.Apache.REEF.IMRU.Tests/Org.Apache.REEF.IMRU.Tests.csproj
----------------------------------------------------------------------
diff --git 
a/lang/cs/Org.Apache.REEF.IMRU.Tests/Org.Apache.REEF.IMRU.Tests.csproj 
b/lang/cs/Org.Apache.REEF.IMRU.Tests/Org.Apache.REEF.IMRU.Tests.csproj
index c5120f2..d9c4668 100644
--- a/lang/cs/Org.Apache.REEF.IMRU.Tests/Org.Apache.REEF.IMRU.Tests.csproj
+++ b/lang/cs/Org.Apache.REEF.IMRU.Tests/Org.Apache.REEF.IMRU.Tests.csproj
@@ -48,6 +48,7 @@ under the License.
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="MapperCountTest.cs" />
     <Compile Include="TestSystemStates.cs" />
+    <Compile Include="TestTaskStates.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference 
Include="$(SolutionDir)\Org.Apache.REEF.IMRU\Org.Apache.REEF.IMRU.csproj">

http://git-wip-us.apache.org/repos/asf/reef/blob/2ee2ca98/lang/cs/Org.Apache.REEF.IMRU.Tests/TestTaskStates.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.IMRU.Tests/TestTaskStates.cs 
b/lang/cs/Org.Apache.REEF.IMRU.Tests/TestTaskStates.cs
new file mode 100644
index 0000000..0c858da
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.IMRU.Tests/TestTaskStates.cs
@@ -0,0 +1,251 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using Org.Apache.REEF.IMRU.OnREEF.Driver.StateMachine;
+using Xunit;
+
+namespace Org.Apache.REEF.IMRU.Tests
+{
+    /// <summary>
+    /// The test cases in this classes test TaskState and transitions
+    /// </summary>
+    public class TestTaskStates
+    {
+        /// <summary>
+        /// This is to test a successful life cycle of task state transitions.
+        /// For TaskNew->TaskSubmitted->TaskRunning->TaskCompleted
+        /// </summary>
+        [Fact]
+        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.");
+        }
+
+        /// <summary>
+        /// This is to test a scenario from task running to close.
+        /// </summary>
+        [Fact]
+        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.");
+        }
+
+        /// <summary>
+        /// This is to test scenario from waiting for close and then get 
FailedTaskCommunicationError.
+        /// </summary>
+        [Fact]
+        public void TestRunningToCloseToFailedTaskCommunicationErrorScenario()
+        {
+            var taskState = new TaskStateMachine();
+            taskState.MoveNext(TaskStateEvent.SubmittedTask);
+            taskState.MoveNext(TaskStateEvent.RunningTask);
+            taskState.MoveNext(TaskStateEvent.WaitingTaskToClose);
+            
Assert.True(taskState.MoveNext(TaskStateEvent.FailedTaskCommunicationError).Equals(TaskState.TaskClosedByDriver),
 "Failed to move from WaitingTaskToClose to TaskClosedByDriver state with 
FailedTaskCommunicationError.");
+        }
+
+        /// <summary>
+        /// This is to test scenario from waiting for close and then get 
FailedTaskAppError.
+        /// </summary>
+        [Fact]
+        public void TestRunningToCloseToFailedTaskAppErrorScenario()
+        {
+            var taskState = new TaskStateMachine();
+            taskState.MoveNext(TaskStateEvent.SubmittedTask);
+            taskState.MoveNext(TaskStateEvent.RunningTask);
+            taskState.MoveNext(TaskStateEvent.WaitingTaskToClose);
+            
Assert.True(taskState.MoveNext(TaskStateEvent.FailedTaskAppError).Equals(TaskState.TaskClosedByDriver),
 "Failed to move from WaitingTaskToClose to TaskClosedByDriver state with 
FailedTaskAppError.");
+        }
+
+        /// <summary>
+        /// This is to test scenario from waiting for close and then get 
FailedTaskSystemError.
+        /// </summary>
+        [Fact]
+        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.");
+        }
+
+        /// <summary>
+        /// This is to test scenario from waiting for close and then get 
FailedTaskEvaluatorError.
+        /// </summary>
+        [Fact]
+        public void TestRunningToCloseToFailedTaskEvaluatorErrorScenario()
+        {
+            var taskState = new TaskStateMachine();
+            taskState.MoveNext(TaskStateEvent.SubmittedTask);
+            taskState.MoveNext(TaskStateEvent.RunningTask);
+            taskState.MoveNext(TaskStateEvent.WaitingTaskToClose);
+            
Assert.True(taskState.MoveNext(TaskStateEvent.FailedTaskEvaluatorError).Equals(TaskState.TaskClosedByDriver),
 "Failed to move from WaitingTaskToClose to TaskClosedByDriver state with 
FailedTaskEvaluatorError.");
+        }
+
+        /// <summary>
+        /// This is to test from WaitingTaskToClose to not allowed transitions.
+        /// </summary>
+        [Fact]
+        public void TestRunningToWaitingTaskToCloseToNotAllowedTransitions()
+        {
+            var taskState = new TaskStateMachine();
+            taskState.MoveNext(TaskStateEvent.SubmittedTask);
+            taskState.MoveNext(TaskStateEvent.RunningTask);
+            taskState.MoveNext(TaskStateEvent.WaitingTaskToClose);
+
+            Action moveNext = () => 
taskState.MoveNext(TaskStateEvent.RunningTask);
+            Assert.Throws<TaskStateTransitionException>(moveNext);
+
+            moveNext = () => taskState.MoveNext(TaskStateEvent.CompletedTask);
+            Assert.Throws<TaskStateTransitionException>(moveNext);
+
+            moveNext = () => taskState.MoveNext(TaskStateEvent.SubmittedTask);
+            Assert.Throws<TaskStateTransitionException>(moveNext);
+        }
+
+        /// <summary>
+        /// This is to test from RunningTask to TaskFailedByEvaluatorFailure.
+        /// </summary>
+        [Fact]
+        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.");
+        }
+
+        /// <summary>
+        /// This is to test from RunningTask to TaskFailedByGroupCommunication 
and then TaskFailedByEvaluatorFailure.
+        /// </summary>
+        [Fact]
+        public void TestRunningToFailByCommunicationThenByEvaluatorScenario()
+        {
+            var taskState = new TaskStateMachine();
+            taskState.MoveNext(TaskStateEvent.SubmittedTask);
+            taskState.MoveNext(TaskStateEvent.RunningTask);
+            
Assert.True(taskState.MoveNext(TaskStateEvent.FailedTaskCommunicationError).Equals(TaskState.TaskFailedByGroupCommunication),
 "Failed to move from RunningTask to TaskFailedByGroupCommunication state with 
FailedTaskCommunicationError.");
+            Assert.True(taskState.IsFinalState(), 
"TaskFailedByGroupCommunication should be a final state.");
+            
Assert.True(taskState.MoveNext(TaskStateEvent.FailedTaskEvaluatorError).Equals(TaskState.TaskFailedByEvaluatorFailure),
 "Failed to move from TaskFailedByGroupCommunication to 
TaskFailedByEvaluatorFailure state with FailedTaskEvaluatorError.");
+            Assert.True(taskState.IsFinalState(), 
"TaskFailedByEvaluatorFailure should be a final state.");
+        }
+
+        /// <summary>
+        /// This is to test from RunningTask to TaskFailedByGroupCommunication 
and then TaskFailedByEvaluatorFailure.
+        /// </summary>
+        [Fact]
+        public void TestRunningToFailBySystemThenByEvaluatorScenario()
+        {
+            var taskState = new TaskStateMachine();
+            taskState.MoveNext(TaskStateEvent.SubmittedTask);
+            taskState.MoveNext(TaskStateEvent.RunningTask);
+            
Assert.True(taskState.MoveNext(TaskStateEvent.FailedTaskSystemError).Equals(TaskState.TaskFailedBySystemError),
 "Failed to move from RunningTask to TaskFailedBySystemError state with 
FailedTaskSystemError.");
+            Assert.True(taskState.IsFinalState(), 
"TaskFailedByGroupCommunication should be a final state.");
+            
Assert.True(taskState.MoveNext(TaskStateEvent.FailedTaskEvaluatorError).Equals(TaskState.TaskFailedByEvaluatorFailure),
 "Failed to move from TaskFailedBySystemError to TaskFailedByEvaluatorFailure 
state with FailedTaskEvaluatorError.");
+            Assert.True(taskState.IsFinalState(), 
"TaskFailedByEvaluatorFailure should be a final state.");
+        }
+
+        /// <summary>
+        /// This is to test from TaskNew to not allowed transitions
+        /// </summary>
+        [Fact]
+        public void TestFromNewToNotAllowedTransitions()
+        {
+            var taskState = new TaskStateMachine();
+            
+            Action moveNext = () => 
taskState.MoveNext(TaskStateEvent.RunningTask);
+            Assert.Throws<TaskStateTransitionException>(moveNext);
+
+            moveNext = () => 
taskState.MoveNext(TaskStateEvent.WaitingTaskToClose);
+            Assert.Throws<TaskStateTransitionException>(moveNext);
+
+            moveNext = () => taskState.MoveNext(TaskStateEvent.CompletedTask);
+            Assert.Throws<TaskStateTransitionException>(moveNext);
+        }
+
+        /// <summary>
+        /// This is to test from RunningTask to not allowed transitions
+        /// </summary>
+        [Fact]
+        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);
+        }
+
+        /// <summary>
+        /// This is to test from FailedTaskEvaluatorError to not allowed 
transitions
+        /// </summary>
+        [Fact]
+        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); 
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/2ee2ca98/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/IMRUSystemException.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/IMRUSystemException.cs 
b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/IMRUSystemException.cs
index 94cf619..7815bdf 100644
--- a/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/IMRUSystemException.cs
+++ b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/IMRUSystemException.cs
@@ -24,7 +24,7 @@ namespace Org.Apache.REEF.IMRU.OnREEF.Driver
     /// Type of exception thrown when possible bugs are detected in IMRU code.
     /// For example, we reach forbidden region of codes, inconsistent state 
etc.
     /// </summary>
-    public sealed class IMRUSystemException : Exception
+    public class IMRUSystemException : Exception
     {
         private static readonly Logger Logger = 
Logger.GetLogger(typeof(IMRUSystemException));
 

http://git-wip-us.apache.org/repos/asf/reef/blob/2ee2ca98/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/SystemStateMachine.cs
----------------------------------------------------------------------
diff --git 
a/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/SystemStateMachine.cs 
b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/SystemStateMachine.cs
index 00963cd..e54e104 100644
--- 
a/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/SystemStateMachine.cs
+++ 
b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/SystemStateMachine.cs
@@ -23,7 +23,7 @@ namespace Org.Apache.REEF.IMRU.OnREEF.Driver.StateMachine
     /// <summary>
     /// This is a state transition machine which wraps current state, defines 
valid state transitions and API to move to next state. 
     /// All the system states are defined in <see cref="SystemState"></see>
-    /// For the system state transition diagram <see 
href="https://issues.apache.org/jira/browse/REEF-1335";></see>
+    /// For the system state transition diagram <see 
href="https://issues.apache.org/jira/browse/REEF-1223";></see>
     /// </summary>
     internal sealed class SystemStateMachine
     {

http://git-wip-us.apache.org/repos/asf/reef/blob/2ee2ca98/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/SystemStateTransitionException.cs
----------------------------------------------------------------------
diff --git 
a/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/SystemStateTransitionException.cs
 
b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/SystemStateTransitionException.cs
index 741cfa0..448927a 100644
--- 
a/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/SystemStateTransitionException.cs
+++ 
b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/SystemStateTransitionException.cs
@@ -15,7 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-using System;
 using System.Globalization;
 
 namespace Org.Apache.REEF.IMRU.OnREEF.Driver.StateMachine
@@ -23,7 +22,7 @@ namespace Org.Apache.REEF.IMRU.OnREEF.Driver.StateMachine
     /// <summary>
     /// Exception for SystemState Transition
     /// </summary>
-    internal sealed class SystemStateTransitionException : Exception
+    internal sealed class SystemStateTransitionException : IMRUSystemException
     {
         /// <summary>
         /// Exception when error happens in system state transition

http://git-wip-us.apache.org/repos/asf/reef/blob/2ee2ca98/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskState.cs
----------------------------------------------------------------------
diff --git 
a/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskState.cs 
b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskState.cs
new file mode 100644
index 0000000..6cb0687
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskState.cs
@@ -0,0 +1,75 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+namespace Org.Apache.REEF.IMRU.OnREEF.Driver.StateMachine
+{
+    /// <summary>
+    /// Task states in task state transitions
+    /// </summary>
+    internal enum TaskState
+    {
+        /// <summary>
+        /// When task (task configuration) is first created and added in the 
task list, its state is TaskNew
+        /// </summary>
+        TaskNew,
+
+        /// <summary>
+        /// After submitting a task with an IActiveContext, the task state is 
changed to TaskSubmittedg
+        /// </summary>
+        TaskSubmitted,
+
+        /// <summary>
+        /// After receiving RunningTask event, the task state is TaskRunning
+        /// </summary>
+        TaskRunning,
+
+        /// <summary>
+        /// After receiving CompletedTask event, the task state is 
TaskCompeleted
+        /// </summary>
+        TaskCompleted,
+
+        /// <summary>
+        /// After driver sends command to close a task, the task state is set 
to TaskWaitingForClose
+        /// </summary>
+        TaskWaitingForClose,
+
+        /// <summary>
+        /// After receiving FailedTask event and verified it is closed by 
driver, the state is set to TaskClosedByDriver
+        /// </summary>
+        TaskClosedByDriver,
+
+        /// <summary>
+        /// After receiving FailedEvaluator event, set associated task state 
to TaskFailedByEvaluatorFailure
+        /// </summary>
+        TaskFailedByEvaluatorFailure,
+
+        /// <summary>
+        /// After receiving FailedTask event and verified it is caused by 
group communication
+        /// </summary>
+        TaskFailedByGroupCommunication,  
+
+        /// <summary>
+        /// After receiving FailedTask event and verified it is caused by 
application error
+        /// </summary>
+        TaskFailedByAppError,
+
+        /// <summary>
+        /// After receiving FailedTask event and verified it is caused by 
system error
+        /// </summary>
+        TaskFailedBySystemError
+    }
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/2ee2ca98/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskStateEvent.cs
----------------------------------------------------------------------
diff --git 
a/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskStateEvent.cs 
b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskStateEvent.cs
new file mode 100644
index 0000000..9668f16
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskStateEvent.cs
@@ -0,0 +1,70 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+namespace Org.Apache.REEF.IMRU.OnREEF.Driver.StateMachine
+{
+    /// <summary>
+    /// Task state events that triggers task state transition
+    /// </summary>
+    internal enum TaskStateEvent
+    {
+        /// <summary>
+        /// Task is submitted
+        /// </summary>
+        SubmittedTask,
+
+        /// <summary>
+        /// Task is running
+        /// </summary>
+        RunningTask,
+
+        /// <summary>
+        /// Task is completed
+        /// </summary>
+        CompletedTask,
+
+        /// <summary>
+        /// Waiting for task to close
+        /// </summary>
+        WaitingTaskToClose,
+
+        /// <summary>
+        /// Task is closed
+        /// </summary>
+        ClosedTask,
+
+        /// <summary>
+        /// Received failed task with application error
+        /// </summary>
+        FailedTaskAppError,
+
+        /// <summary>
+        /// Received failed task with system error
+        /// </summary>
+        FailedTaskSystemError,
+
+        /// <summary>
+        /// Received failed Evaluator that caused associated task failure
+        /// </summary>
+        FailedTaskEvaluatorError,
+
+        /// <summary>
+        /// Received failed task with group communication error
+        /// </summary>
+        FailedTaskCommunicationError
+    }
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/2ee2ca98/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskStateMachine.cs
----------------------------------------------------------------------
diff --git 
a/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskStateMachine.cs 
b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskStateMachine.cs
new file mode 100644
index 0000000..17c0764
--- /dev/null
+++ 
b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskStateMachine.cs
@@ -0,0 +1,145 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace Org.Apache.REEF.IMRU.OnREEF.Driver.StateMachine
+{
+    /// <summary>
+    /// Task state machine which defines task state transition from creating a 
new task, to submitted task, to task running, until task is completed. 
+    /// It also defines the state transition condition from one to another
+    /// All the task states are defined in <see cref="TaskState"></see>
+    /// For the task state transition diagram <see 
href="https://issues.apache.org/jira/browse/REEF-1223";></see>
+    /// This class wraps current state and provides methods to move from one 
state to the next state
+    /// </summary>
+    internal sealed class TaskStateMachine
+    {
+        private readonly static IDictionary<StateTransition<TaskState, 
TaskStateEvent>, TaskState> Transitions = new 
ReadOnlyDictionary<StateTransition<TaskState, TaskStateEvent>, TaskState>(
+            new Dictionary<StateTransition<TaskState, TaskStateEvent>, 
TaskState>
+        {
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskNew, TaskStateEvent.SubmittedTask), 
TaskState.TaskSubmitted },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskNew, TaskStateEvent.ClosedTask), 
TaskState.TaskClosedByDriver },            
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskSubmitted, TaskStateEvent.RunningTask), 
TaskState.TaskRunning },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskSubmitted, TaskStateEvent.FailedTaskAppError), 
TaskState.TaskFailedByAppError },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskSubmitted, TaskStateEvent.FailedTaskSystemError), 
TaskState.TaskFailedBySystemError },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskSubmitted, 
TaskStateEvent.FailedTaskEvaluatorError), 
TaskState.TaskFailedByEvaluatorFailure },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskSubmitted, 
TaskStateEvent.FailedTaskCommunicationError), 
TaskState.TaskFailedByGroupCommunication },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskRunning, TaskStateEvent.CompletedTask), 
TaskState.TaskCompleted },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskRunning, TaskStateEvent.WaitingTaskToClose), 
TaskState.TaskWaitingForClose },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskRunning, TaskStateEvent.FailedTaskAppError), 
TaskState.TaskFailedByAppError },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskRunning, TaskStateEvent.FailedTaskSystemError), 
TaskState.TaskFailedBySystemError },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskRunning, 
TaskStateEvent.FailedTaskEvaluatorError), 
TaskState.TaskFailedByEvaluatorFailure },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskRunning, 
TaskStateEvent.FailedTaskCommunicationError), 
TaskState.TaskFailedByGroupCommunication },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskWaitingForClose, TaskStateEvent.ClosedTask), 
TaskState.TaskClosedByDriver },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskWaitingForClose, 
TaskStateEvent.FailedTaskAppError), TaskState.TaskClosedByDriver },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskWaitingForClose, 
TaskStateEvent.FailedTaskSystemError), TaskState.TaskClosedByDriver },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskWaitingForClose, 
TaskStateEvent.FailedTaskEvaluatorError), TaskState.TaskClosedByDriver },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskWaitingForClose, 
TaskStateEvent.FailedTaskCommunicationError), TaskState.TaskClosedByDriver },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskFailedBySystemError, 
TaskStateEvent.FailedTaskEvaluatorError), 
TaskState.TaskFailedByEvaluatorFailure },
+            { new StateTransition<TaskState, 
TaskStateEvent>(TaskState.TaskFailedByGroupCommunication, 
TaskStateEvent.FailedTaskEvaluatorError), 
TaskState.TaskFailedByEvaluatorFailure }
+        });
+
+        /// <summary>
+        /// Final state means that the task is not running and will not 
attempt to run. 
+        /// When all tasks are in final states, we can proceed to recovery or 
fail. 
+        /// Transitions between final states are possible if causes of task 
termination are clarified. For example, we might receive 
+        /// FailedTask event first, then set the task state as 
TaskFailedBySystemError or TaskFailedByGroupCommunication. And later 
+        /// received FailedEvaluator that indicates the attached task was 
failed is actually caused by evaluator failure. We can then 
+        /// change the state to TaskFailedByEvaluatorFailure.
+        /// For the task state transition diagram <see 
href="https://issues.apache.org/jira/browse/REEF-1223";></see>
+        /// </summary>
+        private readonly static ISet<TaskState> FinalState = new 
HashSet<TaskState>()
+        {
+            TaskState.TaskFailedByAppError,
+            TaskState.TaskFailedBySystemError,
+            TaskState.TaskFailedByEvaluatorFailure,
+            TaskState.TaskFailedByGroupCommunication,
+            TaskState.TaskClosedByDriver,
+            TaskState.TaskCompleted
+        };
+
+        private volatile TaskState _currentState;
+
+        /// <summary>
+        /// Create a new DriverTaskState with TaskNew as the task initial state
+        /// </summary>
+        internal TaskStateMachine()
+        {
+            _currentState = TaskState.TaskNew;
+        }
+
+        /// <summary>
+        /// return the current task state
+        /// </summary>
+        internal TaskState CurrentState
+        {
+            get
+            {
+                return _currentState;
+            }
+        }
+
+        /// <summary>
+        /// Get next valid state based on the current state and event given 
without changing the current state
+        /// If there is no valid next state, TaskStateTransitionException will 
be thrown.
+        /// </summary>
+        /// <param name="taskEvent"></param>
+        /// <returns></returns>
+        internal TaskState GetNext(TaskStateEvent taskEvent)
+        {
+            StateTransition<TaskState, TaskStateEvent> transition = new 
StateTransition<TaskState, TaskStateEvent>(_currentState, taskEvent);
+            TaskState nextState;
+            if (!Transitions.TryGetValue(transition, out nextState))
+            {
+                throw new TaskStateTransitionException(_currentState, 
taskEvent);
+            }
+            return nextState;
+        }
+
+        /// <summary>
+        /// Move to the next state
+        /// If it is not able to move to the next valid state for a given 
event, TaskStateTransitionException will be thrown.
+        /// </summary>
+        /// <param name="taskEvent"></param>
+        /// <returns></returns>
+        internal TaskState MoveNext(TaskStateEvent taskEvent)
+        {
+            _currentState = GetNext(taskEvent);
+            return _currentState;
+        }
+
+        /// <summary>
+        /// Checks if the current state is a final state
+        /// </summary>
+        /// <returns></returns>
+        internal bool IsFinalState()
+        {
+            return IsFinalState(_currentState);
+        }
+
+        /// <summary>
+        /// Checks if the given TaskState is a final state
+        /// </summary>
+        /// <param name="taskState"></param>
+        /// <returns></returns>
+        internal static bool IsFinalState(TaskState taskState)
+        {
+            return FinalState.Contains(taskState);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/2ee2ca98/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskStateTransitionException.cs
----------------------------------------------------------------------
diff --git 
a/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskStateTransitionException.cs
 
b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskStateTransitionException.cs
new file mode 100644
index 0000000..a1b6e93
--- /dev/null
+++ 
b/lang/cs/Org.Apache.REEF.IMRU/OnREEF/Driver/StateMachine/TaskStateTransitionException.cs
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System.Globalization;
+
+namespace Org.Apache.REEF.IMRU.OnREEF.Driver.StateMachine
+{
+    /// <summary>
+    /// Exception for TaskState Transition
+    /// </summary>
+    internal sealed class TaskStateTransitionException : IMRUSystemException
+    {
+        /// <summary>
+        /// Exception when error happens in task state transition
+        /// </summary>
+        /// <param name="taskState"></param>
+        /// <param name="taskEvent"></param>
+        internal TaskStateTransitionException(TaskState taskState, 
TaskStateEvent taskEvent)
+            : base(ExceptionMessage(taskState, taskEvent))
+        {            
+        }
+
+        /// <summary>
+        /// Format a message
+        /// </summary>
+        /// <param name="taskState"></param>
+        /// <param name="taskEvent"></param>
+        /// <returns></returns>
+        private static string ExceptionMessage(TaskState taskState, 
TaskStateEvent taskEvent)
+        {
+            return string.Format(CultureInfo.InvariantCulture, "Unexpected 
event {0} in state {1}.", taskEvent, taskState);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/2ee2ca98/lang/cs/Org.Apache.REEF.IMRU/Org.Apache.REEF.IMRU.csproj
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.IMRU/Org.Apache.REEF.IMRU.csproj 
b/lang/cs/Org.Apache.REEF.IMRU/Org.Apache.REEF.IMRU.csproj
index 7c6c8f3..d893d49 100644
--- a/lang/cs/Org.Apache.REEF.IMRU/Org.Apache.REEF.IMRU.csproj
+++ b/lang/cs/Org.Apache.REEF.IMRU/Org.Apache.REEF.IMRU.csproj
@@ -76,11 +76,15 @@ under the License.
     <Compile Include="OnREEF\Driver\IMRUConstants.cs" />
     <Compile Include="OnREEF\Driver\IMRUDriver.cs" />
     <Compile Include="OnREEF\Driver\ServiceAndContextConfigurationProvider.cs" 
/>
+    <Compile Include="OnREEF\Driver\StateMachine\TaskStateMachine.cs" />
     <Compile Include="OnREEF\Driver\StateMachine\StateTransition.cs" />
     <Compile Include="OnREEF\Driver\StateMachine\SystemState.cs" />
     <Compile Include="OnREEF\Driver\StateMachine\SystemStateEvent.cs" />
     <Compile Include="OnREEF\Driver\StateMachine\SystemStateMachine.cs" />
     <Compile 
Include="OnREEF\Driver\StateMachine\SystemStateTransitionException.cs" />
+    <Compile Include="OnREEF\Driver\StateMachine\TaskStateEvent.cs" />
+    <Compile Include="OnREEF\Driver\StateMachine\TaskState.cs" />
+    <Compile 
Include="OnREEF\Driver\StateMachine\TaskStateTransitionException.cs" />
     <Compile Include="OnREEF\IMRUTasks\MapTaskHost.cs" />
     <Compile Include="OnREEF\IMRUTasks\UpdateTaskHost.cs" />
     <Compile Include="OnREEF\MapInputWithControlMessage\MapControlMessage.cs" 
/>

Reply via email to