You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by br...@apache.org on 2013/11/14 20:19:14 UTC

git commit: Added list of TaskStatuses to Task message.

Updated Branches:
  refs/heads/master bb4db98a9 -> 480f8a71f


Added list of TaskStatuses to Task message.

Task now includes repeated task status with timestamps.  This permits
caltulating the start/finish time for tasks (among other things).

To support this, a timestamp was added to the TaskStatus message which
is also passed to frameworks when there are state transitions.

Review: https://reviews.apache.org/r/14434


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/480f8a71
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/480f8a71
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/480f8a71

Branch: refs/heads/master
Commit: 480f8a71f6ad8c0698937249445e6405e6443c9c
Parents: bb4db98
Author: Brenden Matthews <br...@airbnb.com>
Authored: Tue Oct 1 16:21:44 2013 -0700
Committer: Brenden Matthews <br...@airbnb.com>
Committed: Thu Nov 14 11:19:07 2013 -0800

----------------------------------------------------------------------
 include/mesos/mesos.proto                 |  5 +--
 src/common/protobuf_utils.hpp             |  1 +
 src/exec/exec.cpp                         |  1 +
 src/master/http.cpp                       | 19 +++++++++++
 src/master/master.cpp                     |  5 +++
 src/messages/messages.proto               |  2 +-
 src/slave/slave.cpp                       | 16 ++++++---
 src/slave/slave.hpp                       |  2 +-
 src/webui/master/static/framework.html    | 45 ++++++++++++++++++++++++++
 src/webui/master/static/frameworks.html   |  2 +-
 src/webui/master/static/js/controllers.js |  4 +++
 11 files changed, 92 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/480f8a71/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index ad4ba5b..655f867 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -394,6 +394,7 @@ message TaskStatus {
   optional string message = 4; // Possible message explaining state.
   optional bytes data = 3;
   optional SlaveID slave_id = 5;
+  optional double timestamp = 6;
 }
 
 
@@ -434,8 +435,8 @@ message Parameter {
   required string key = 1;
   required string value = 2;
 }
- 
- 
+
+
 /**
  * Collection of Parameter.
  */

http://git-wip-us.apache.org/repos/asf/mesos/blob/480f8a71/src/common/protobuf_utils.hpp
----------------------------------------------------------------------
diff --git a/src/common/protobuf_utils.hpp b/src/common/protobuf_utils.hpp
index 19a49ab..c83cbd6 100644
--- a/src/common/protobuf_utils.hpp
+++ b/src/common/protobuf_utils.hpp
@@ -66,6 +66,7 @@ inline StatusUpdate createStatusUpdate(
   status->mutable_slave_id()->MergeFrom(slaveId);
   status->set_state(state);
   status->set_message(message);
+  status->set_timestamp(update.timestamp());
 
   return update;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/480f8a71/src/exec/exec.cpp
----------------------------------------------------------------------
diff --git a/src/exec/exec.cpp b/src/exec/exec.cpp
index 4a598f5..c866838 100644
--- a/src/exec/exec.cpp
+++ b/src/exec/exec.cpp
@@ -495,6 +495,7 @@ protected:
     update->mutable_slave_id()->MergeFrom(slaveId);
     update->mutable_status()->MergeFrom(status);
     update->set_timestamp(Clock::now().secs());
+    update->mutable_status()->set_timestamp(update->timestamp());
     update->set_uuid(UUID::random().toBytes());
     message.set_pid(self());
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/480f8a71/src/master/http.cpp
----------------------------------------------------------------------
diff --git a/src/master/http.cpp b/src/master/http.cpp
index f2a535a..deb5c97 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -38,6 +38,7 @@
 #include "common/attributes.hpp"
 #include "common/build.hpp"
 #include "common/type_utils.hpp"
+#include "common/protobuf_utils.hpp"
 
 #include "logging/logging.hpp"
 
@@ -121,6 +122,17 @@ JSON::Object model(const Attributes& attributes)
 }
 
 
+// Returns a JSON object modeled on a TaskStatus.
+JSON::Object model(const TaskStatus& status)
+{
+  JSON::Object object;
+  object.values["state"] = TaskState_Name(status.state());
+  object.values["timestamp"] = status.timestamp();
+
+  return object;
+}
+
+
 // Returns a JSON object modeled on a Task.
 // TODO(bmahler): Expose the executor name / source.
 JSON::Object model(const Task& task)
@@ -133,6 +145,13 @@ JSON::Object model(const Task& task)
   object.values["slave_id"] = task.slave_id().value();
   object.values["state"] = TaskState_Name(task.state());
   object.values["resources"] = model(task.resources());
+
+  JSON::Array array;
+  foreach (const TaskStatus& status, task.statuses()) {
+    array.values.push_back(model(status));
+  }
+  object.values["statuses"] = array;
+
   return object;
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/480f8a71/src/master/master.cpp
----------------------------------------------------------------------
diff --git a/src/master/master.cpp b/src/master/master.cpp
index 8e14a07..abab6ce 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -1417,6 +1417,11 @@ void Master::statusUpdate(const StatusUpdate& update, const UPID& pid)
 
   LOG(INFO) << "Status update " << update << " from " << pid;
 
+  // TODO(brenden) Consider wiping the `data` and `message` fields?
+  if (task->state() == status.state()) {
+    task->mutable_statuses()->RemoveLast();
+  }
+  task->add_statuses()->CopyFrom(status);
   task->set_state(status.state());
 
   // Handle the task appropriately if it's terminated.

http://git-wip-us.apache.org/repos/asf/mesos/blob/480f8a71/src/messages/messages.proto
----------------------------------------------------------------------
diff --git a/src/messages/messages.proto b/src/messages/messages.proto
index a5dded2..71f68a0 100644
--- a/src/messages/messages.proto
+++ b/src/messages/messages.proto
@@ -46,9 +46,9 @@ message Task {
   required SlaveID slave_id = 5;
   required TaskState state = 6;
   repeated Resource resources = 7;
+  repeated TaskStatus statuses = 8;
 }
 
-
 // Describes a role, which are used to group frameworks for allocation
 // decisions, depending on the allocation policy being used.
 // The weight field can be used to indicate forms of priority.

http://git-wip-us.apache.org/repos/asf/mesos/blob/480f8a71/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index 13cb418..bb98fce 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -1812,7 +1812,7 @@ void Slave::statusUpdate(const StatusUpdate& update, const UPID& pid)
   stats.tasks[update.status().state()]++;
   stats.validStatusUpdates++;
 
-  executor->updateTaskState(status.task_id(), status.state());
+  executor->updateTaskState(status);
 
   // Handle the task appropriately if it is terminated.
   // TODO(vinod): Revisit these semantics when we disallow duplicate
@@ -3250,7 +3250,7 @@ void Executor::recoverTask(const TaskState& state)
 
   // Read updates to get the latest state of the task.
   foreach (const StatusUpdate& update, state.updates) {
-    updateTaskState(state.id, update.status().state());
+    updateTaskState(update.status());
 
     // Terminate the task if it received a terminal update.
     // We ignore duplicate terminal updates by checking if
@@ -3271,10 +3271,16 @@ void Executor::recoverTask(const TaskState& state)
 }
 
 
-void Executor::updateTaskState(const TaskID& taskId, mesos::TaskState state)
+void Executor::updateTaskState(const TaskStatus& status)
 {
-  if (launchedTasks.contains(taskId)) {
-    launchedTasks[taskId]->set_state(state);
+  if (launchedTasks.contains(status.task_id())) {
+    Task* task = launchedTasks[status.task_id()];
+    // TODO(brenden): Consider wiping the `data` and `message` fields?
+    if (task->state() == status.state()) {
+      task->mutable_statuses()->RemoveLast();
+    }
+    task->add_statuses()->CopyFrom(status);
+    task->set_state(status.state());
   }
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/480f8a71/src/slave/slave.hpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.hpp b/src/slave/slave.hpp
index 68526f3..b39eaf4 100644
--- a/src/slave/slave.hpp
+++ b/src/slave/slave.hpp
@@ -366,7 +366,7 @@ struct Executor
   void completeTask(const TaskID& taskId);
   void checkpointTask(const TaskInfo& task);
   void recoverTask(const state::TaskState& state);
-  void updateTaskState(const TaskID& taskId, TaskState state);
+  void updateTaskState(const TaskStatus& status);
 
   // Returns true if there are any queued/launched/terminated tasks.
   bool incompleteTasks();

http://git-wip-us.apache.org/repos/asf/mesos/blob/480f8a71/src/webui/master/static/framework.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/framework.html b/src/webui/master/static/framework.html
index 6e5cd9f..368f0f3 100644
--- a/src/webui/master/static/framework.html
+++ b/src/webui/master/static/framework.html
@@ -74,6 +74,10 @@
               ng-click="selectColumn('active_tasks', 'state')">
             State
           </th>
+          <th ng-class="columnClass('active_tasks', 'start_time')"
+              ng-click="selectColumn('active_tasks', 'start_time')">
+            Started
+          </th>
           <th ng-class="columnClass('active_tasks', 'host')"
               ng-click="selectColumn('active_tasks', 'host')">
             Host
@@ -91,6 +95,17 @@
           <td>{{task.name}}</td>
           <td>{{task.state | truncateMesosState}}</td>
           <td>
+            <abbr title="{{task.start_time | isoDate}}">
+              {{task.start_time | relativeDate}}</abbr>
+            <button class="btn btn-mini btn-toggle"
+              clipboard
+              data-clipboard-text="{{task.start_time | isoDate}}"
+              tooltip="Copy start time"
+              tooltip-placement="right"
+              tooltip-trigger="clipboardhover">
+            </button>
+          </td>
+          <td>
             <span data-ng-show="slaves[task.slave_id]">
               {{slaves[task.slave_id].hostname}}
             </span>
@@ -126,6 +141,14 @@
               ng-click="selectColumn('completed_tasks', 'state')">
             State
           </th>
+          <th ng-class="columnClass('completed_tasks', 'start_time')"
+              ng-click="selectColumn('completed_tasks', 'start_time')">
+            Started
+          </th>
+          <th ng-class="columnClass('completed_tasks', 'finish_time')"
+              ng-click="selectColumn('completed_tasks', 'finish_time')">
+            Stopped
+          </th>
           <th ng-class="columnClass('completed_tasks', 'host')"
               ng-click="selectColumn('completed_tasks', 'host')">
             Host
@@ -140,6 +163,28 @@
           <td>{{task.name}}</td>
           <td>{{task.state | truncateMesosState}}</td>
           <td>
+            <abbr title="{{task.start_time | isoDate}}">
+              {{task.start_time | relativeDate}}</abbr>
+            <button class="btn btn-mini btn-toggle"
+              clipboard
+              data-clipboard-text="{{task.start_time | isoDate}}"
+              tooltip="Copy start time"
+              tooltip-placement="right"
+              tooltip-trigger="clipboardhover">
+            </button>
+          </td>
+          <td>
+            <abbr title="{{task.finish_time | isoDate}}">
+              {{task.finish_time | relativeDate}}</abbr>
+            <button class="btn btn-mini btn-toggle"
+              clipboard
+              data-clipboard-text="{{task.finish_time | isoDate}}"
+              tooltip="Copy finish time"
+              tooltip-placement="right"
+              tooltip-trigger="clipboardhover">
+            </button>
+          </td>
+          <td>
             <a data-ng-show="slaves[task.slave_id]"
                 href="#/slaves/{{task.slave_id}}/frameworks/{{task.framework_id}}/executors/{{task.executor_id}}">
               {{slaves[task.slave_id].hostname}}

http://git-wip-us.apache.org/repos/asf/mesos/blob/480f8a71/src/webui/master/static/frameworks.html
----------------------------------------------------------------------
diff --git a/src/webui/master/static/frameworks.html b/src/webui/master/static/frameworks.html
index 7c243d4..6cf5194 100644
--- a/src/webui/master/static/frameworks.html
+++ b/src/webui/master/static/frameworks.html
@@ -98,4 +98,4 @@
       </tbody>
     </table>
   </div>
-</div>
\ No newline at end of file
+</div>

http://git-wip-us.apache.org/repos/asf/mesos/blob/480f8a71/src/webui/master/static/js/controllers.js
----------------------------------------------------------------------
diff --git a/src/webui/master/static/js/controllers.js b/src/webui/master/static/js/controllers.js
index 8f65679..6f74859 100644
--- a/src/webui/master/static/js/controllers.js
+++ b/src/webui/master/static/js/controllers.js
@@ -221,11 +221,15 @@
         if (!task.executor_id) {
           task.executor_id = task.id;
         }
+        task.start_time = task.statuses[0].timestamp * 1000
+        task.finish_time = task.statuses[task.statuses.length - 1].timestamp * 1000
       });
       _.each(framework.completed_tasks, function(task) {
         if (!task.executor_id) {
           task.executor_id = task.id;
         }
+        task.start_time = task.statuses[0].timestamp * 1000
+        task.finish_time = task.statuses[task.statuses.length - 1].timestamp * 1000
       });
     });