You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tez.apache.org by je...@apache.org on 2014/12/10 04:34:00 UTC

[37/53] tez git commit: TEZ-1794. Vertex view needs a task attempt rollup (Prakash Ramachandran via Rajesh Balamohan)

TEZ-1794. Vertex view needs a task attempt rollup (Prakash Ramachandran via Rajesh Balamohan)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/8af5ea38
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/8af5ea38
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/8af5ea38

Branch: refs/heads/master
Commit: 8af5ea389d9732027131b71f7c315629add4d5c8
Parents: 8f3ceaa
Author: Rajesh Balamohan <rb...@hortonworks.com>
Authored: Thu Nov 20 16:08:18 2014 +0530
Committer: Rajesh Balamohan <rb...@hortonworks.com>
Committed: Thu Nov 20 16:08:18 2014 +0530

----------------------------------------------------------------------
 .../scripts/controllers/vertex_controller.js    |   3 +-
 .../controllers/vertex_index_controller.js      |  12 ++
 .../vertex_task_attempts_controller.js          | 171 +++++++++++++++++++
 .../app/scripts/helpers/handlebarHelpers.js     |   4 +
 tez-ui/src/main/webapp/app/scripts/router.js    |  16 ++
 tez-ui/src/main/webapp/app/styles/main.less     |   4 +
 .../webapp/app/templates/common/configs.hbs     |  25 +++
 .../webapp/app/templates/taskAttempt/index.hbs  |   4 +
 .../main/webapp/app/templates/vertex/index.hbs  |  65 +++++++
 .../app/templates/vertex/task_attempts.hbs      |  46 +++++
 10 files changed, 349 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/8af5ea38/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js
index 51bd1dc..b2acacb 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_controller.js
@@ -34,8 +34,9 @@ App.VertexController = Em.ObjectController.extend(App.Helpers.DisplayHelper, {
   childDisplayViews: [
     Ember.Object.create({title: 'Details', linkTo: 'vertex.index'}),
     Ember.Object.create({title: 'Tasks', linkTo: 'vertex.tasks'}),
+    Ember.Object.create({title: 'Task Attempts', linkTo: 'vertex.taskAttempts'}),
     Ember.Object.create({title: 'Counters', linkTo: 'vertex.counters'}),
     Ember.Object.create({title: 'Swimlane', linkTo: 'vertex.swimlane'}),
     Ember.Object.create({title: 'Inputs', linkTo: 'vertex.inputs'}),
   ],
-});
\ No newline at end of file
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8af5ea38/tez-ui/src/main/webapp/app/scripts/controllers/vertex_index_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_index_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_index_controller.js
index cec39c4..a7b16c3 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_index_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_index_controller.js
@@ -31,4 +31,16 @@ App.VertexIndexController = Em.ObjectController.extend({
   failedTasksLink: function() {
     return '#tasks?status=FAILED&parentType=TEZ_VERTEX_ID&parentID=' + this.get('id');
   }.property(),
+
+  hasFirstTaskStarted: function() {
+    return !!this.get('firstTaskStartTime') && !!this.get('firstTasksToStart');
+  }.property(),
+
+  hasLastTaskFinished: function() {
+    return !!this.get('lastTaskFinishTime') && !!this.get('lastTasksToFinish');
+  }.property(),
+
+  hasStats: function() {
+    return !!this.get('avgTaskDuration') || !!this.get('minTaskDuration') || !!this.get('maxTaskDuration');
+  }.property()
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/8af5ea38/tez-ui/src/main/webapp/app/scripts/controllers/vertex_task_attempts_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_task_attempts_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_task_attempts_controller.js
new file mode 100644
index 0000000..70ceb76
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_task_attempts_controller.js
@@ -0,0 +1,171 @@
+/**
+ * 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.
+ */
+
+App.VertexTaskAttemptsController = Em.ObjectController.extend(App.PaginatedContentMixin, {
+  // Required by the PaginatedContentMixin
+  childEntityType: 'taskAttempt',
+
+  needs: 'vertex',
+
+  queryParams: {
+    status_filter: 'status',
+  },
+  status_filter: null,
+
+  loadData: function() {
+    var filters = {
+      primary: {
+        TEZ_VERTEX_ID: this.get('controllers.vertex.id')
+      },
+      secondary: {
+        status: this.status_filter
+      }
+    }
+    this.setFiltersAndLoadEntities(filters);
+  },
+
+  actions : {
+    filterUpdated: function(filterID, value) {
+      // any validations required goes here.
+      if (!!value) {
+        this.set(filterID, value);
+      } else {
+        this.set(filterID, null);
+      }
+      this.loadData();
+    }
+  },
+
+  columns: function() {
+    var idCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Task ID',
+      tableCellViewClass: Em.Table.TableCell.extend({
+        template: Em.Handlebars.compile(
+          "{{#link-to 'task' view.cellContent class='ember-table-content'}}{{view.cellContent}}{{/link-to}}")
+      }),
+      contentPath: 'taskID',
+    });
+
+    var attemptNoCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Attempt No',
+      tableCellViewClass: Em.Table.TableCell.extend({
+        template: Em.Handlebars.compile(
+          "{{#link-to 'taskAttempt' view.cellContent.attemptID class='ember-table-content'}}{{view.cellContent.attemptNo}}{{/link-to}}")
+      }),
+      getCellContent: function(row) {
+        var attemptID = row.get('id') || '',
+            attemptNo = attemptID.split(/[_]+/).pop();
+        return {
+          attemptNo: attemptNo,
+          attemptID: attemptID
+        };
+      }
+    });
+
+    var startTimeCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Start Time',
+      getCellContent: function(row) {
+        return App.Helpers.date.dateFormat(row.get('startTime'));
+      }
+    });
+
+    var endTimeCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'End Time',
+      getCellContent: function(row) {
+        return App.Helpers.date.dateFormat(row.get('endTime'));
+      }
+    });
+
+    var durationCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'duration',
+      getCellContent: function(row) {
+        var st = row.get('startTime');
+        var et = row.get('endTime');
+        if (st && et) {
+          return App.Helpers.date.durationSummary(st, et);
+        }
+      }
+    });
+
+    var statusCol = App.ExTable.ColumnDefinition.createWithMixins(App.ExTable.FilterColumnMixin,{
+      headerCellName: 'Status',
+      filterID: 'status_filter',
+      filterType: 'dropdown',
+      dropdownValues: App.Helpers.misc.taskStatusUIOptions,
+      tableCellViewClass: Em.Table.TableCell.extend({
+        template: Em.Handlebars.compile(
+          '<span class="ember-table-content">&nbsp;\
+          <i {{bind-attr class=":task-status view.cellContent.statusIcon"}}></i>\
+          &nbsp;&nbsp;{{view.cellContent.status}}</span>')
+      }),
+      getCellContent: function(row) {
+        return {
+          status: row.get('status'),
+          statusIcon: App.Helpers.misc.getStatusClassForEntity(row)
+        };
+      }
+    });
+
+    var containerCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Container',
+      contentPath: 'containerId'
+    });
+
+    var nodeCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Node',
+      contentPath: 'nodeId'
+    });
+
+    var actionsCol = App.ExTable.ColumnDefinition.create({
+      headerCellName: 'Actions',
+      tableCellViewClass: Em.Table.TableCell.extend({
+        template: Em.Handlebars.compile(
+          '<span class="ember-table-content">\
+          {{#link-to "taskAttempt.counters" view.cellContent}}counters{{/link-to}}&nbsp;\
+          </span>'
+          )
+      }),
+      contentPath: 'id'
+    });
+
+    var logs = App.ExTable.ColumnDefinition.create({
+      textAlign: 'text-align-left',
+      headerCellName: 'Logs',
+      tableCellViewClass: Em.Table.TableCell.extend({
+        template: Em.Handlebars.compile(
+          '<span class="ember-table-content">\
+            {{#unless view.cellContent}}\
+              Not Available\
+            {{else}}\
+              <a href="//{{unbound view.cellContent}}">View</a>\
+              &nbsp;\
+              <a href="//{{unbound view.cellContent}}?start=0" download target="_blank" type="application/octet-stream">Download</a>\
+            {{/unless}}\
+          </span>')
+      }),
+      getCellContent: function(row) {
+        var attempt = row.get('pivotAttempt');
+        var logFile = attempt && (attempt.get('inProgressLog') || attempt.get('completedLog'));
+        if(logFile) logFile += "/syslog_" + attempt.get('id');
+        return logFile;
+      }
+    });
+
+    return [idCol, attemptNoCol, startTimeCol, endTimeCol, durationCol, statusCol, containerCol, nodeCol, actionsCol, logs];
+  }.property(),
+});

http://git-wip-us.apache.org/repos/asf/tez/blob/8af5ea38/tez-ui/src/main/webapp/app/scripts/helpers/handlebarHelpers.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/helpers/handlebarHelpers.js b/tez-ui/src/main/webapp/app/scripts/helpers/handlebarHelpers.js
index 72e3b0e..3639d28 100644
--- a/tez-ui/src/main/webapp/app/scripts/helpers/handlebarHelpers.js
+++ b/tez-ui/src/main/webapp/app/scripts/helpers/handlebarHelpers.js
@@ -47,6 +47,10 @@ Em.Handlebars.helper('formatDuration', function(startTime, endTime) {
 	return App.Helpers.date.durationSummary(startTime, endTime);
 });
 
+Em.Handlebars.helper('formatTimeMillis', function(duration) {
+  return App.Helpers.date.timingFormat(duration, true);
+});
+
 function replaceAll(str, str1, str2, ignore) 
 {
     return str.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2);

http://git-wip-us.apache.org/repos/asf/tez/blob/8af5ea38/tez-ui/src/main/webapp/app/scripts/router.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/router.js b/tez-ui/src/main/webapp/app/scripts/router.js
index 7810670..f8633e8 100644
--- a/tez-ui/src/main/webapp/app/scripts/router.js
+++ b/tez-ui/src/main/webapp/app/scripts/router.js
@@ -36,6 +36,7 @@ App.Router.map(function() {
     this.resource('vertexInput', {path: '/input/:input_id'}, function(){
       this.route('configs');
     });
+    this.route('taskAttempts');
     this.route('counters');
     this.route('details');
     this.route('swimlane');
@@ -208,6 +209,17 @@ App.VertexTasksRoute = Em.Route.extend({
   }
 });
 
+App.VertexTaskAttemptsRoute = Em.Route.extend({
+  queryParams: {
+    status: App.Helpers.misc.defaultQueryParamsConfig
+  },
+
+  setupController: function(controller, model) {
+    this._super(controller, model);
+    controller.loadData();
+  }
+});
+
 App.TaskAttemptsRoute = Em.Route.extend({
   queryParams: {
     status: App.Helpers.misc.defaultQueryParamsConfig 
@@ -223,6 +235,10 @@ App.TaskAttemptsRoute = Em.Route.extend({
 App.VertexInputConfigsRoute = App.TezAppConfigsRoute = Em.Route.extend({
   renderTemplate: function() {
     this.render('common/configs');
+  },
+  setupController: function(controller, model) {
+    this._super(controller, model)
+    controller.set('needToShowInputDetails', this.routeName === 'vertexInput.configs');
   }
 });
 

http://git-wip-us.apache.org/repos/asf/tez/blob/8af5ea38/tez-ui/src/main/webapp/app/styles/main.less
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/styles/main.less b/tez-ui/src/main/webapp/app/styles/main.less
index 790c309..3823d47 100644
--- a/tez-ui/src/main/webapp/app/styles/main.less
+++ b/tez-ui/src/main/webapp/app/styles/main.less
@@ -53,6 +53,10 @@
 	margin: 30px;
 }
 
+.margin-medium-horizontal {
+  margin: 30px 0px;
+}
+
 .type-table {
 	display: table;
 }

http://git-wip-us.apache.org/repos/asf/tez/blob/8af5ea38/tez-ui/src/main/webapp/app/templates/common/configs.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/common/configs.hbs b/tez-ui/src/main/webapp/app/templates/common/configs.hbs
index dfc18d3..d6d5e2d 100644
--- a/tez-ui/src/main/webapp/app/templates/common/configs.hbs
+++ b/tez-ui/src/main/webapp/app/templates/common/configs.hbs
@@ -16,6 +16,31 @@
 * limitations under the License.
 }}
 
+{{#if needToShowInputDetails}}
+  <div class='align-left margin-medium-horizontal'>
+    <table class='detail-list'>
+      <thead>
+        <tr>
+          <th>Input Details</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr>
+          <td>Name</td>
+          <td>{{inputName}}</td>
+        </tr>
+        <tr>
+          <td>Class</td>
+          <td>{{inputClass}}</td>
+        </tr>
+        <tr>
+          <td>Initializer</td>
+          <td>{{inputInitializer}}</td>
+        </tr>
+      </tbody>
+    </table>
+  </div>
+{{/if}}
 <div class='table-container'>
   {{kv-table-component data=configs}}
 </div>

http://git-wip-us.apache.org/repos/asf/tez/blob/8af5ea38/tez-ui/src/main/webapp/app/templates/taskAttempt/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/taskAttempt/index.hbs b/tez-ui/src/main/webapp/app/templates/taskAttempt/index.hbs
index db17b2e..4fbf0f1 100644
--- a/tez-ui/src/main/webapp/app/templates/taskAttempt/index.hbs
+++ b/tez-ui/src/main/webapp/app/templates/taskAttempt/index.hbs
@@ -13,6 +13,10 @@
 					<td>Container</td>
 					<td>{{containerId}}</td>
 				</tr>
+        <tr>
+          <td>Node</td>
+          <td>{{nodeId}}</td>
+        </tr>
 			</tbody>
 		</table>
 	</div>

http://git-wip-us.apache.org/repos/asf/tez/blob/8af5ea38/tez-ui/src/main/webapp/app/templates/vertex/index.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/vertex/index.hbs b/tez-ui/src/main/webapp/app/templates/vertex/index.hbs
index ba2955e..f6b7502 100644
--- a/tez-ui/src/main/webapp/app/templates/vertex/index.hbs
+++ b/tez-ui/src/main/webapp/app/templates/vertex/index.hbs
@@ -56,6 +56,27 @@
           <td>Killed Tasks</td>
           <td>{{killedTasks}}</td>
         </tr>
+        {{#if hasFirstTaskStarted}}
+          <tr>
+            <td>First Task Start Time</td>
+            <td>{{formatUnixTimestamp firstTaskStartTime}}
+            <td>
+              {{#each taskid in firstTasksToStart}}
+                {{#link-to 'task' taskid}}{{taskid}}{{/link-to}}<br/>
+              {{/each}}
+            </td>
+          </tr>
+        {{/if}}
+        {{#if hasLastTaskFinished}}
+          <tr>
+            <td>Last Task Finish Time</td>
+            <td>{{formatUnixTimestamp lastTaskFinishTime}}
+            <td>
+              {{#each taskid in lastTasksToFinish}}
+                {{#link-to 'task' taskid}}{{taskid}}{{/link-to}}<br/>
+              {{/each}}
+          </tr>
+        {{/if}}
       </tbody>
     </table>
   </div>
@@ -77,6 +98,50 @@
       </tbody>
     </table>
   </div>
+
+  <div class='align-clear margin-medium'></div>
+  {{#if hasStats}}
+    <div class='align-left'>
+      <table class='detail-list'>
+        <thead>
+          <tr>
+            <th>Task Stats</th>
+          </tr>
+        </thead>
+        <tbody>
+          {{#if avgTaskDuration}}
+            <tr>
+              <td>Average Duration</td>
+              <td>{{formatTimeMillis avgTaskDuration}}</td>
+            </tr>
+          {{/if}}
+          {{#if minTaskDuration}}
+            <tr>
+              <td>Minimum Duration</td>
+              <td>{{formatTimeMillis minTaskDuration}}</td>
+              <td>
+                {{#each taskid in shortestDurationTasks}}
+                  {{#link-to 'task' taskid}}{{taskid}}{{/link-to}}<br/>
+                {{/each}}
+              </td>
+            </tr>
+          {{/if}}
+          {{#if maxTaskDuration}}
+            <tr>
+              <td>Maximum Duration</td>
+              <td>{{formatTimeMillis maxTaskDuration}}</td>
+              <td>
+                {{#each taskid in longestDurationTasks}}
+                  {{#link-to 'task' taskid}}{{taskid}}{{/link-to}}<br/>
+                {{/each}}
+              </td>
+            </tr>
+          {{/if}}
+        </tbody>
+      </table>
+    </div>
+  {{/if}}
+
 </div>
 
 {{#if diagnostics}}

http://git-wip-us.apache.org/repos/asf/tez/blob/8af5ea38/tez-ui/src/main/webapp/app/templates/vertex/task_attempts.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/vertex/task_attempts.hbs b/tez-ui/src/main/webapp/app/templates/vertex/task_attempts.hbs
new file mode 100644
index 0000000..7224117
--- /dev/null
+++ b/tez-ui/src/main/webapp/app/templates/vertex/task_attempts.hbs
@@ -0,0 +1,46 @@
+{{!
+* 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.
+}}
+
+{{#unless loading}}
+  <div class='margin-small'>
+    <span class='align-left'>
+      {{page-nav-component
+        hasPrev=hasPrev
+        hasNext=hasNext
+        navNext='navigateNext'
+        navPrev='navigatePrev'
+        navFirst='navigateFirst'
+      }}
+    </span>
+    <div class='align-clear'> </div>
+  </div>
+
+  <div class='table-container'>
+  {{extended-table-component
+    hasFooter=false
+    enableContentSelection=true
+    columnsBinding="columns"
+    contentBinding="sortedContent"
+    forceFillColumns=true
+    hasFilter=true
+    onFilterUpdated='filterUpdated'
+  }}
+  </div>
+{{else}}
+  {{partial 'utils/loadingSpinner'}}
+{{/unless}}
\ No newline at end of file