[FLINK-3310] [runtime-web] Add back pressure statistics to web dashboard 
(frontend)

This closes #1578.


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

Branch: refs/heads/master
Commit: ba13caa1bc10cfd4c94cdc89f674b64751a83a17
Parents: b7e70da
Author: Ufuk Celebi <u...@apache.org>
Authored: Mon Feb 1 21:01:26 2016 +0100
Committer: Ufuk Celebi <u...@apache.org>
Committed: Mon Feb 8 15:05:00 2016 +0100

----------------------------------------------------------------------
 .../app/partials/jobs/job.plan.jade             |     3 +
 .../jobs/job.plan.node-list.backpressure.jade   |    77 +
 .../app/scripts/common/directives.coffee        |    15 +
 .../app/scripts/common/filters.coffee           |     2 +
 .../web-dashboard/app/scripts/index.coffee      |     7 +
 .../app/scripts/modules/jobs/jobs.ctrl.coffee   |    20 +
 .../app/scripts/modules/jobs/jobs.svc.coffee    |    18 +
 .../web-dashboard/web/css/vendor.css            | 13843 +++++++------
 .../web-dashboard/web/fonts/FontAwesome.otf     |   Bin 109688 -> 93888 bytes
 .../web/fonts/fontawesome-webfont.eot           |   Bin 70807 -> 60767 bytes
 .../web/fonts/fontawesome-webfont.svg           |   134 +-
 .../web/fonts/fontawesome-webfont.ttf           |   Bin 142072 -> 122092 bytes
 .../web/fonts/fontawesome-webfont.woff          |   Bin 83588 -> 71508 bytes
 .../web/fonts/fontawesome-webfont.woff2         |   Bin 66624 -> 56780 bytes
 flink-runtime-web/web-dashboard/web/js/index.js |    72 +-
 .../web-dashboard/web/js/vendor.js              | 17901 +++++++----------
 .../web/partials/jobs/job.plan.html             |     1 +
 .../jobs/job.plan.node-list.backpressure.html   |    80 +
 18 files changed, 14323 insertions(+), 17850 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flink/blob/ba13caa1/flink-runtime-web/web-dashboard/app/partials/jobs/job.plan.jade
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/app/partials/jobs/job.plan.jade 
b/flink-runtime-web/web-dashboard/app/partials/jobs/job.plan.jade
index 5dc2632..46eeec6 100644
--- a/flink-runtime-web/web-dashboard/app/partials/jobs/job.plan.jade
+++ b/flink-runtime-web/web-dashboard/app/partials/jobs/job.plan.jade
@@ -30,4 +30,7 @@
       li(ui-sref-active='active')
         a(ui-sref=".checkpoints({nodeid: nodeid})") Checkpoints
 
+      li(ng-if="job.state == 'RUNNING'" ui-sref-active='active')
+        a(ui-sref=".backpressure({nodeid: nodeid})") Back Pressure
+
   .panel-body.clean(ui-view="node-details")

http://git-wip-us.apache.org/repos/asf/flink/blob/ba13caa1/flink-runtime-web/web-dashboard/app/partials/jobs/job.plan.node-list.backpressure.jade
----------------------------------------------------------------------
diff --git 
a/flink-runtime-web/web-dashboard/app/partials/jobs/job.plan.node-list.backpressure.jade
 
b/flink-runtime-web/web-dashboard/app/partials/jobs/job.plan.node-list.backpressure.jade
new file mode 100644
index 0000000..bf7f077
--- /dev/null
+++ 
b/flink-runtime-web/web-dashboard/app/partials/jobs/job.plan.node-list.backpressure.jade
@@ -0,0 +1,77 @@
+//
+  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.
+
+table.table.table-body-hover.table-clickable.table-activable
+  thead
+    tr
+      th Name
+      th Status
+
+  tbody(ng-repeat="v in job.vertices" ng-class="{ active: v.id == nodeid }" 
ng-click="v.id == nodeid || changeNode(v.id)")
+    tr(ng-if="v.type == 'regular'")
+      td {{ v.name | humanizeText }}
+      td
+        bs-label(status="{{v.status}}") {{v.status}}
+    tr(ng-if="nodeid && v.id == nodeid")
+      td(ng-if="v.status != 'RUNNING'" colspan=2)
+        p Operator is not running. Cannot sample back pressure.
+      td(ng-if="v.status == 'RUNNING'" colspan=2)
+        table.table.table-hover.table-clickable.table-activable.table-inner
+          thead
+            tr
+              th Measurement
+              th Back Pressure Status
+          tbody
+            tr
+              td
+                span(ng-if="backPressureOperatorStats[v.id]['end-timestamp']") 
{{ now - backPressureOperatorStats[v.id]['end-timestamp'] | humanizeDuration }} 
ago
+                span(ng-if="backPressureOperatorStats[v.id]['status'] == 
'deprecated'")
+                  bp-label(status="in-progress") Sampling in progress...
+              td
+                
bp-label(ng-if="backPressureOperatorStats[v.id]['backpressure-level']" 
status="{{backPressureOperatorStats[v.id]['backpressure-level']}}") {{ 
backPressureOperatorStats[v.id]['backpressure-level'] | toUpperCase }}
+
+        div(ng-if="!nodeUnfolded && 
backPressureOperatorStats[v.id]['subtasks'] && 
backPressureOperatorStats[v.id]['subtasks'].length > 0")
+          a.btn.btn-default(ng-click="toggleFold()")
+            | Show subtasks
+            = ' '
+            i.fa.fa-chevron-down
+
+          a.btn.btn-default.pull-right(ng-click="deactivateNode(); 
$event.stopPropagation()" title="Fold")
+            i.fa.fa-chevron-up
+
+        div(ng-if="nodeUnfolded && backPressureOperatorStats[v.id]['subtasks'] 
&& backPressureOperatorStats[v.id]['subtasks'].length > 0")
+          a.btn.btn-default(ng-click="toggleFold()")
+            | Hide subtasks
+            = ' '
+            i.fa.fa-chevron-up
+
+          a.btn.btn-default.pull-right(ng-click="deactivateNode(); 
$event.stopPropagation()" title="Fold")
+            i.fa.fa-chevron-up
+
+          table.table.table-hover.table-clickable.table-activable.table-inner
+            thead
+              tr
+                th Subtask
+                th Ratio
+                th Status
+            tbody
+              tr(ng-repeat="subtask in 
backPressureOperatorStats[nodeid]['subtasks']")
+                td {{ subtask['subtask'] + 1 }}
+                td {{ subtask['ratio'] }}
+                td
+                  bp-label(status="{{subtask['backpressure-level']}}") {{ 
subtask['backpressure-level'] | toUpperCase }}
+

http://git-wip-us.apache.org/repos/asf/flink/blob/ba13caa1/flink-runtime-web/web-dashboard/app/scripts/common/directives.coffee
----------------------------------------------------------------------
diff --git 
a/flink-runtime-web/web-dashboard/app/scripts/common/directives.coffee 
b/flink-runtime-web/web-dashboard/app/scripts/common/directives.coffee
index 98212ee..39fbd50 100644
--- a/flink-runtime-web/web-dashboard/app/scripts/common/directives.coffee
+++ b/flink-runtime-web/web-dashboard/app/scripts/common/directives.coffee
@@ -35,6 +35,21 @@ angular.module('flinkApp')
 
 # ----------------------------------------------
 
+.directive 'bpLabel', (JobsService) ->
+  transclude: true
+  replace: true
+  scope:
+    getBackPressureLabelClass: "&"
+    status: "@"
+
+  template: "<span title='{{status}}' 
ng-class='getBackPressureLabelClass()'><ng-transclude></ng-transclude></span>"
+
+  link: (scope, element, attrs) ->
+    scope.getBackPressureLabelClass = ->
+      'label label-' + 
JobsService.translateBackPressureLabelState(attrs.status)
+
+# ----------------------------------------------
+
 .directive 'indicatorPrimary', (JobsService) ->
   replace: true
   scope: 

http://git-wip-us.apache.org/repos/asf/flink/blob/ba13caa1/flink-runtime-web/web-dashboard/app/scripts/common/filters.coffee
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/app/scripts/common/filters.coffee 
b/flink-runtime-web/web-dashboard/app/scripts/common/filters.coffee
index 473adc3..093c599 100644
--- a/flink-runtime-web/web-dashboard/app/scripts/common/filters.coffee
+++ b/flink-runtime-web/web-dashboard/app/scripts/common/filters.coffee
@@ -73,3 +73,5 @@ angular.module('flinkApp')
     return "" if typeof bytes is "undefined" or bytes is null
     if bytes < 1000 then bytes + " B" else converter(bytes, 1)
 
+.filter "toUpperCase", ->
+  (text) -> text.toUpperCase()

http://git-wip-us.apache.org/repos/asf/flink/blob/ba13caa1/flink-runtime-web/web-dashboard/app/scripts/index.coffee
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/app/scripts/index.coffee 
b/flink-runtime-web/web-dashboard/app/scripts/index.coffee
index 07e13ff..07e5265 100644
--- a/flink-runtime-web/web-dashboard/app/scripts/index.coffee
+++ b/flink-runtime-web/web-dashboard/app/scripts/index.coffee
@@ -113,6 +113,13 @@ angular.module('flinkApp', ['ui.router', 'angularMoment'])
         templateUrl: "partials/jobs/job.plan.node-list.checkpoints.html"
         controller: 'JobPlanCheckpointsController'
 
+  .state "single-job.plan.backpressure",
+    url: "/backpressure"
+    views:
+      'node-details':
+        templateUrl: "partials/jobs/job.plan.node-list.backpressure.html"
+        controller: 'JobPlanBackPressureController'
+
   .state "single-job.timeline",
     url: "/timeline"
     views:

http://git-wip-us.apache.org/repos/asf/flink/blob/ba13caa1/flink-runtime-web/web-dashboard/app/scripts/modules/jobs/jobs.ctrl.coffee
----------------------------------------------------------------------
diff --git 
a/flink-runtime-web/web-dashboard/app/scripts/modules/jobs/jobs.ctrl.coffee 
b/flink-runtime-web/web-dashboard/app/scripts/modules/jobs/jobs.ctrl.coffee
index 899a099..37ce217 100644
--- a/flink-runtime-web/web-dashboard/app/scripts/modules/jobs/jobs.ctrl.coffee
+++ b/flink-runtime-web/web-dashboard/app/scripts/modules/jobs/jobs.ctrl.coffee
@@ -51,6 +51,7 @@ angular.module('flinkApp')
   $scope.vertices = null
   $scope.jobCheckpointStats = null
   $scope.showHistory = false
+  $scope.backPressureOperatorStats = {}
 
   JobsService.loadJob($stateParams.jobid).then (data) ->
     $scope.job = data
@@ -70,6 +71,7 @@ angular.module('flinkApp')
     $scope.plan = null
     $scope.vertices = null
     $scope.jobCheckpointStats = null
+    $scope.backPressureOperatorStats = null
 
     $interval.cancel(refresher)
 
@@ -179,6 +181,24 @@ angular.module('flinkApp')
 
 # --------------------------------------
 
+.controller 'JobPlanBackPressureController', ($scope, JobsService) ->
+  console.log 'JobPlanBackPressureController'
+  $scope.now = Date.now()
+
+  if $scope.nodeid
+    JobsService.getOperatorBackPressure($scope.nodeid).then (data) ->
+      $scope.backPressureOperatorStats[$scope.nodeid] = data
+
+  $scope.$on 'reload', (event) ->
+    console.log 'JobPlanBackPressureController (relaod)'
+    $scope.now = Date.now()
+
+    if $scope.nodeid
+      JobsService.getOperatorBackPressure($scope.nodeid).then (data) ->
+        $scope.backPressureOperatorStats[$scope.nodeid] = data
+
+# --------------------------------------
+
 .controller 'JobTimelineVertexController', ($scope, $state, $stateParams, 
JobsService) ->
   console.log 'JobTimelineVertexController'
 

http://git-wip-us.apache.org/repos/asf/flink/blob/ba13caa1/flink-runtime-web/web-dashboard/app/scripts/modules/jobs/jobs.svc.coffee
----------------------------------------------------------------------
diff --git 
a/flink-runtime-web/web-dashboard/app/scripts/modules/jobs/jobs.svc.coffee 
b/flink-runtime-web/web-dashboard/app/scripts/modules/jobs/jobs.svc.coffee
index 404647b..8756496 100644
--- a/flink-runtime-web/web-dashboard/app/scripts/modules/jobs/jobs.svc.coffee
+++ b/flink-runtime-web/web-dashboard/app/scripts/modules/jobs/jobs.svc.coffee
@@ -232,6 +232,24 @@ angular.module('flinkApp')
 
     deferred.promise
 
+  # Operator-level back pressure stats
+  @getOperatorBackPressure = (vertexid) ->
+    deferred = $q.defer()
+
+    $http.get flinkConfig.jobServer + "jobs/" + currentJob.jid + "/vertices/" 
+ vertexid + "/backpressure"
+    .success (data) =>
+      deferred.resolve(data)
+
+    deferred.promise
+
+  @translateBackPressureLabelState = (state) ->
+    switch state.toLowerCase()
+      when 'in-progress' then 'danger'
+      when 'ok' then 'success'
+      when 'low' then 'warning'
+      when 'high' then 'danger'
+      else 'default'
+
   @loadExceptions = ->
     deferred = $q.defer()
 

Reply via email to