| /* |
| * 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. |
| */ |
| |
| /* |
| * Licensed under the Apache License, Version 2.0 |
| * See accompanying LICENSE file. |
| */ |
| |
| angular.module('dashboard') |
| |
| .config(['$stateProvider', |
| function ($stateProvider) { |
| 'use strict'; |
| |
| $stateProvider |
| .state('streamingapp', { |
| abstract: true, |
| url: '/apps/streamingapp/:appId', |
| templateUrl: 'views/apps/streamingapp/streamingapp.html', |
| controller: 'StreamingAppCtrl', |
| resolve: { |
| app0: ['$stateParams', 'models', function ($stateParams, models) { |
| return models.$get.app($stateParams.appId); |
| }] |
| } |
| }); |
| }]) |
| |
| /** |
| * This controller is used to obtain app. All nested views will read status from here. |
| */ |
| .controller('StreamingAppCtrl', ['$scope', '$state', 'i18n', 'helper', 'models', 'app0', |
| function ($scope, $state, i18n, helper, models, app0) { |
| 'use strict'; |
| |
| $scope.whatIsAppClock = i18n.terminology.appClock; |
| $scope.$state = $state; // required by streamingapp.html |
| $scope.app = app0; |
| $scope.metricsConfig = app0.historyMetricsConfig; |
| $scope.uptimeCompact = helper.readableDuration(app0.uptime); |
| $scope.dag = models.createDag(app0.clock, app0.processors, app0.dag.edgeList); |
| |
| app0.$subscribe($scope, function (app) { |
| updateAppDetails(app); |
| }, /*onerror=*/ function () { |
| // manually reset status fields on an error response |
| var app = angular.copy($scope.app); |
| app.status = 'terminated'; |
| app.isRunning = false; |
| _.forEach(app.executors, function (executor) { |
| executor.status = 'terminated'; |
| executor.isRunning = false; |
| }); |
| updateAppDetails(app); |
| }); |
| |
| function updateAppDetails(app) { |
| $scope.app = app; |
| $scope.uptimeCompact = helper.readableDuration(app.uptime); |
| $scope.dag.setData(app.clock, app.processors, app.dag.edgeList); |
| } |
| |
| models.$get.appStallingTasks(app0.appId) |
| .then(function (tasks0) { |
| updateStallingTasks(tasks0.$data()); |
| tasks0.$subscribe($scope, function (tasks) { |
| updateStallingTasks(tasks); |
| }); |
| }); |
| function updateStallingTasks(tasks) { |
| $scope.appClockConcern = ($scope.app.isRunning && Object.keys(tasks).length) ? |
| "Application clock does not go forward. Click here to check red processor(s)." : undefined; |
| $scope.dag.setStallingTasks(tasks); |
| } |
| |
| $scope.switchToDagTab = function () { |
| $state.go('streamingapp.dag'); |
| }; |
| |
| // As metrics will be collected shortly after application is started, we should not receive initial metrics |
| // at the view resolving stage. |
| models.$subscribe($scope, |
| function () { |
| return models.$get.appLatestMetrics(app0.appId); |
| }, |
| function (metrics0) { |
| $scope.metrics = metrics0.$data(); |
| metrics0.$subscribe($scope, function (metrics) { |
| $scope.metrics = metrics; |
| }); |
| }); |
| $scope.$watch('metrics', function (metrics) { |
| if (angular.isObject(metrics)) { |
| $scope.dag.updateLatestMetrics(metrics); |
| } |
| }); |
| |
| // Angular template cannot call the function directly, so export a function. |
| $scope.size = function (obj) { |
| return Object.keys(obj).length; |
| }; |
| |
| $scope.sendThroughputMetricsCaption = 'Source Processors Send Throughput'; |
| $scope.sendThroughputMetricsDescription = 'Messages are sent from source processors'; |
| $scope.receiveThroughputMetricsCaption = 'Sink Processors Receive Throughput'; |
| $scope.receiveThroughputMetricsDescription = 'Messages are received by sink processors'; |
| $scope.messageLatencyMetricsCaption = 'End-to-End Latency'; |
| $scope.messageLatencyMetricsDescription = 'The largest latency from a source processor to a sink processor. The value is the sum of message receive latency plus message processing time of all processors on the path (except the source processor).'; |
| $scope.averageMessageProcessingTimeMetricsCaption = 'Average Message Processing Time'; |
| $scope.averageMessageProcessingTimeMetricsDescription = 'The processing time is the duration from a message is received by a processor and to the message is sent to the next stop'; |
| }]) |
| ; |