blob: bc7a9cde2cd181bba345e084bfda05d93d3bdc4c [file] [log] [blame]
/*
* 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';
}])
;