You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by uc...@apache.org on 2017/01/12 14:49:09 UTC
[3/5] flink git commit: [FLINK-5466] [webfrontend] Rebuild CSS/JS
files
http://git-wip-us.apache.org/repos/asf/flink/blob/e1181f6c/flink-runtime-web/web-dashboard/web/js/index.js
----------------------------------------------------------------------
diff --git a/flink-runtime-web/web-dashboard/web/js/index.js b/flink-runtime-web/web-dashboard/web/js/index.js
index a2db9c8..b166b8d 100644
--- a/flink-runtime-web/web-dashboard/web/js/index.js
+++ b/flink-runtime-web/web-dashboard/web/js/index.js
@@ -1,2249 +1,2 @@
-angular.module('flinkApp', ['ui.router', 'angularMoment', 'dndLists']).run(["$rootScope", function($rootScope) {
- $rootScope.sidebarVisible = false;
- return $rootScope.showSidebar = function() {
- $rootScope.sidebarVisible = !$rootScope.sidebarVisible;
- return $rootScope.sidebarClass = 'force-show';
- };
-}]).value('flinkConfig', {
- jobServer: '',
- "refresh-interval": 10000
-}).run(["JobsService", "MainService", "flinkConfig", "$interval", function(JobsService, MainService, flinkConfig, $interval) {
- return MainService.loadConfig().then(function(config) {
- angular.extend(flinkConfig, config);
- JobsService.listJobs();
- return $interval(function() {
- return JobsService.listJobs();
- }, flinkConfig["refresh-interval"]);
- });
-}]).config(["$uiViewScrollProvider", function($uiViewScrollProvider) {
- return $uiViewScrollProvider.useAnchorScroll();
-}]).run(["$rootScope", "$state", function($rootScope, $state) {
- return $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState) {
- if (toState.redirectTo) {
- event.preventDefault();
- return $state.go(toState.redirectTo, toParams);
- }
- });
-}]).config(["$stateProvider", "$urlRouterProvider", function($stateProvider, $urlRouterProvider) {
- $stateProvider.state("overview", {
- url: "/overview",
- views: {
- main: {
- templateUrl: "partials/overview.html",
- controller: 'OverviewController'
- }
- }
- }).state("running-jobs", {
- url: "/running-jobs",
- views: {
- main: {
- templateUrl: "partials/jobs/running-jobs.html",
- controller: 'RunningJobsController'
- }
- }
- }).state("completed-jobs", {
- url: "/completed-jobs",
- views: {
- main: {
- templateUrl: "partials/jobs/completed-jobs.html",
- controller: 'CompletedJobsController'
- }
- }
- }).state("single-job", {
- url: "/jobs/{jobid}",
- abstract: true,
- views: {
- main: {
- templateUrl: "partials/jobs/job.html",
- controller: 'SingleJobController'
- }
- }
- }).state("single-job.plan", {
- url: "",
- redirectTo: "single-job.plan.subtasks",
- views: {
- details: {
- templateUrl: "partials/jobs/job.plan.html",
- controller: 'JobPlanController'
- }
- }
- }).state("single-job.plan.subtasks", {
- url: "",
- views: {
- 'node-details': {
- templateUrl: "partials/jobs/job.plan.node-list.subtasks.html",
- controller: 'JobPlanSubtasksController'
- }
- }
- }).state("single-job.plan.metrics", {
- url: "/metrics",
- views: {
- 'node-details': {
- templateUrl: "partials/jobs/job.plan.node-list.metrics.html",
- controller: 'JobPlanMetricsController'
- }
- }
- }).state("single-job.plan.taskmanagers", {
- url: "/taskmanagers",
- views: {
- 'node-details': {
- templateUrl: "partials/jobs/job.plan.node-list.taskmanagers.html",
- controller: 'JobPlanTaskManagersController'
- }
- }
- }).state("single-job.plan.accumulators", {
- url: "/accumulators",
- views: {
- 'node-details': {
- templateUrl: "partials/jobs/job.plan.node-list.accumulators.html",
- controller: 'JobPlanAccumulatorsController'
- }
- }
- }).state("single-job.plan.checkpoints", {
- url: "/checkpoints",
- redirectTo: "single-job.plan.checkpoints.overview",
- views: {
- 'node-details': {
- templateUrl: "partials/jobs/job.plan.node-list.checkpoints.html",
- controller: 'JobPlanCheckpointsController'
- }
- }
- }).state("single-job.plan.checkpoints.overview", {
- url: "/overview",
- views: {
- 'checkpoints-view': {
- templateUrl: "partials/jobs/job.plan.node.checkpoints.overview.html",
- controller: 'JobPlanCheckpointsController'
- }
- }
- }).state("single-job.plan.checkpoints.summary", {
- url: "/summary",
- views: {
- 'checkpoints-view': {
- templateUrl: "partials/jobs/job.plan.node.checkpoints.summary.html",
- controller: 'JobPlanCheckpointsController'
- }
- }
- }).state("single-job.plan.checkpoints.history", {
- url: "/history",
- views: {
- 'checkpoints-view': {
- templateUrl: "partials/jobs/job.plan.node.checkpoints.history.html",
- controller: 'JobPlanCheckpointsController'
- }
- }
- }).state("single-job.plan.checkpoints.config", {
- url: "/config",
- views: {
- 'checkpoints-view': {
- templateUrl: "partials/jobs/job.plan.node.checkpoints.config.html",
- controller: 'JobPlanCheckpointsController'
- }
- }
- }).state("single-job.plan.checkpoints.details", {
- url: "/details/{checkpointId}",
- views: {
- 'checkpoints-view': {
- templateUrl: "partials/jobs/job.plan.node.checkpoints.details.html",
- controller: 'JobPlanCheckpointDetailsController'
- }
- }
- }).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: {
- details: {
- templateUrl: "partials/jobs/job.timeline.html"
- }
- }
- }).state("single-job.timeline.vertex", {
- url: "/{vertexId}",
- views: {
- vertex: {
- templateUrl: "partials/jobs/job.timeline.vertex.html",
- controller: 'JobTimelineVertexController'
- }
- }
- }).state("single-job.exceptions", {
- url: "/exceptions",
- views: {
- details: {
- templateUrl: "partials/jobs/job.exceptions.html",
- controller: 'JobExceptionsController'
- }
- }
- }).state("single-job.config", {
- url: "/config",
- views: {
- details: {
- templateUrl: "partials/jobs/job.config.html"
- }
- }
- }).state("all-manager", {
- url: "/taskmanagers",
- views: {
- main: {
- templateUrl: "partials/taskmanager/index.html",
- controller: 'AllTaskManagersController'
- }
- }
- }).state("single-manager", {
- url: "/taskmanager/{taskmanagerid}",
- abstract: true,
- views: {
- main: {
- templateUrl: "partials/taskmanager/taskmanager.html",
- controller: 'SingleTaskManagerController'
- }
- }
- }).state("single-manager.metrics", {
- url: "/metrics",
- views: {
- details: {
- templateUrl: "partials/taskmanager/taskmanager.metrics.html"
- }
- }
- }).state("single-manager.stdout", {
- url: "/stdout",
- views: {
- details: {
- templateUrl: "partials/taskmanager/taskmanager.stdout.html",
- controller: 'SingleTaskManagerStdoutController'
- }
- }
- }).state("single-manager.log", {
- url: "/log",
- views: {
- details: {
- templateUrl: "partials/taskmanager/taskmanager.log.html",
- controller: 'SingleTaskManagerLogsController'
- }
- }
- }).state("jobmanager", {
- url: "/jobmanager",
- views: {
- main: {
- templateUrl: "partials/jobmanager/index.html"
- }
- }
- }).state("jobmanager.config", {
- url: "/config",
- views: {
- details: {
- templateUrl: "partials/jobmanager/config.html",
- controller: 'JobManagerConfigController'
- }
- }
- }).state("jobmanager.stdout", {
- url: "/stdout",
- views: {
- details: {
- templateUrl: "partials/jobmanager/stdout.html",
- controller: 'JobManagerStdoutController'
- }
- }
- }).state("jobmanager.log", {
- url: "/log",
- views: {
- details: {
- templateUrl: "partials/jobmanager/log.html",
- controller: 'JobManagerLogsController'
- }
- }
- }).state("submit", {
- url: "/submit",
- views: {
- main: {
- templateUrl: "partials/submit.html",
- controller: "JobSubmitController"
- }
- }
- });
- return $urlRouterProvider.otherwise("/overview");
-}]);
-
-angular.module('flinkApp').directive('bsLabel', ["JobsService", function(JobsService) {
- return {
- transclude: true,
- replace: true,
- scope: {
- getLabelClass: "&",
- status: "@"
- },
- template: "<span title='{{status}}' ng-class='getLabelClass()'><ng-transclude></ng-transclude></span>",
- link: function(scope, element, attrs) {
- return scope.getLabelClass = function() {
- return 'label label-' + JobsService.translateLabelState(attrs.status);
- };
- }
- };
-}]).directive('bpLabel', ["JobsService", function(JobsService) {
- return {
- transclude: true,
- replace: true,
- scope: {
- getBackPressureLabelClass: "&",
- status: "@"
- },
- template: "<span title='{{status}}' ng-class='getBackPressureLabelClass()'><ng-transclude></ng-transclude></span>",
- link: function(scope, element, attrs) {
- return scope.getBackPressureLabelClass = function() {
- return 'label label-' + JobsService.translateBackPressureLabelState(attrs.status);
- };
- }
- };
-}]).directive('indicatorPrimary', ["JobsService", function(JobsService) {
- return {
- replace: true,
- scope: {
- getLabelClass: "&",
- status: '@'
- },
- template: "<i title='{{status}}' ng-class='getLabelClass()' />",
- link: function(scope, element, attrs) {
- return scope.getLabelClass = function() {
- return 'fa fa-circle indicator indicator-' + JobsService.translateLabelState(attrs.status);
- };
- }
- };
-}]).directive('tableProperty', function() {
- return {
- replace: true,
- scope: {
- value: '='
- },
- template: "<td title=\"{{value || 'None'}}\">{{value || 'None'}}</td>"
- };
-});
-
-angular.module('flinkApp').filter("amDurationFormatExtended", ["angularMomentConfig", function(angularMomentConfig) {
- var amDurationFormatExtendedFilter;
- amDurationFormatExtendedFilter = function(value, format, durationFormat) {
- if (typeof value === "undefined" || value === null) {
- return "";
- }
- return moment.duration(value, format).format(durationFormat, {
- trim: false
- });
- };
- amDurationFormatExtendedFilter.$stateful = angularMomentConfig.statefulFilters;
- return amDurationFormatExtendedFilter;
-}]).filter("humanizeDuration", function() {
- return function(value, short) {
- var days, hours, minutes, ms, seconds, x;
- if (typeof value === "undefined" || value === null) {
- return "";
- }
- ms = value % 1000;
- x = Math.floor(value / 1000);
- seconds = x % 60;
- x = Math.floor(x / 60);
- minutes = x % 60;
- x = Math.floor(x / 60);
- hours = x % 24;
- x = Math.floor(x / 24);
- days = x;
- if (days === 0) {
- if (hours === 0) {
- if (minutes === 0) {
- if (seconds === 0) {
- return ms + "ms";
- } else {
- return seconds + "s ";
- }
- } else {
- return minutes + "m " + seconds + "s";
- }
- } else {
- if (short) {
- return hours + "h " + minutes + "m";
- } else {
- return hours + "h " + minutes + "m " + seconds + "s";
- }
- }
- } else {
- if (short) {
- return days + "d " + hours + "h";
- } else {
- return days + "d " + hours + "h " + minutes + "m " + seconds + "s";
- }
- }
- };
-}).filter("humanizeText", function() {
- return function(text) {
- if (text) {
- return text.replace(/>/g, ">").replace(/<br\/>/g, "");
- } else {
- return '';
- }
- };
-}).filter("humanizeBytes", function() {
- return function(bytes) {
- var converter, units;
- units = ["B", "KB", "MB", "GB", "TB", "PB", "EB"];
- converter = function(value, power) {
- var base;
- base = Math.pow(1024, power);
- if (value < base) {
- return (value / base).toFixed(2) + " " + units[power];
- } else if (value < base * 1000) {
- return (value / base).toPrecision(3) + " " + units[power];
- } else {
- return converter(value, power + 1);
- }
- };
- if (typeof bytes === "undefined" || bytes === null) {
- return "";
- }
- if (bytes < 1000) {
- return bytes + " B";
- } else {
- return converter(bytes, 1);
- }
- };
-}).filter("toLocaleString", function() {
- return function(text) {
- return text.toLocaleString();
- };
-}).filter("toUpperCase", function() {
- return function(text) {
- return text.toUpperCase();
- };
-}).filter("percentage", function() {
- return function(number) {
- return (number * 100).toFixed(0) + '%';
- };
-});
-
-angular.module('flinkApp').service('MainService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
- this.loadConfig = function() {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "config").success(function(data, status, headers, config) {
- return deferred.resolve(data);
- });
- return deferred.promise;
- };
- return this;
-}]);
-
-angular.module('flinkApp').controller('JobManagerConfigController', ["$scope", "JobManagerConfigService", function($scope, JobManagerConfigService) {
- return JobManagerConfigService.loadConfig().then(function(data) {
- if ($scope.jobmanager == null) {
- $scope.jobmanager = {};
- }
- return $scope.jobmanager['config'] = data;
- });
-}]).controller('JobManagerLogsController', ["$scope", "JobManagerLogsService", function($scope, JobManagerLogsService) {
- JobManagerLogsService.loadLogs().then(function(data) {
- if ($scope.jobmanager == null) {
- $scope.jobmanager = {};
- }
- return $scope.jobmanager['log'] = data;
- });
- return $scope.reloadData = function() {
- return JobManagerLogsService.loadLogs().then(function(data) {
- return $scope.jobmanager['log'] = data;
- });
- };
-}]).controller('JobManagerStdoutController', ["$scope", "JobManagerStdoutService", function($scope, JobManagerStdoutService) {
- JobManagerStdoutService.loadStdout().then(function(data) {
- if ($scope.jobmanager == null) {
- $scope.jobmanager = {};
- }
- return $scope.jobmanager['stdout'] = data;
- });
- return $scope.reloadData = function() {
- return JobManagerStdoutService.loadStdout().then(function(data) {
- return $scope.jobmanager['stdout'] = data;
- });
- };
-}]);
-
-angular.module('flinkApp').service('JobManagerConfigService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
- var config;
- config = {};
- this.loadConfig = function() {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "jobmanager/config").success(function(data, status, headers, config) {
- config = data;
- return deferred.resolve(data);
- });
- return deferred.promise;
- };
- return this;
-}]).service('JobManagerLogsService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
- var logs;
- logs = {};
- this.loadLogs = function() {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "jobmanager/log").success(function(data, status, headers, config) {
- logs = data;
- return deferred.resolve(data);
- });
- return deferred.promise;
- };
- return this;
-}]).service('JobManagerStdoutService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
- var stdout;
- stdout = {};
- this.loadStdout = function() {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "jobmanager/stdout").success(function(data, status, headers, config) {
- stdout = data;
- return deferred.resolve(data);
- });
- return deferred.promise;
- };
- return this;
-}]);
-
-angular.module('flinkApp').controller('OverviewController', ["$scope", "OverviewService", "JobsService", "$interval", "flinkConfig", function($scope, OverviewService, JobsService, $interval, flinkConfig) {
- var refresh;
- $scope.jobObserver = function() {
- $scope.runningJobs = JobsService.getJobs('running');
- return $scope.finishedJobs = JobsService.getJobs('finished');
- };
- JobsService.registerObserver($scope.jobObserver);
- $scope.$on('$destroy', function() {
- return JobsService.unRegisterObserver($scope.jobObserver);
- });
- $scope.jobObserver();
- OverviewService.loadOverview().then(function(data) {
- return $scope.overview = data;
- });
- refresh = $interval(function() {
- return OverviewService.loadOverview().then(function(data) {
- return $scope.overview = data;
- });
- }, flinkConfig["refresh-interval"]);
- return $scope.$on('$destroy', function() {
- return $interval.cancel(refresh);
- });
-}]);
-
-angular.module('flinkApp').service('OverviewService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
- var overview;
- overview = {};
- this.loadOverview = function() {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "overview").success(function(data, status, headers, config) {
- overview = data;
- return deferred.resolve(data);
- });
- return deferred.promise;
- };
- return this;
-}]);
-
-angular.module('flinkApp').controller('RunningJobsController', ["$scope", "$state", "$stateParams", "JobsService", function($scope, $state, $stateParams, JobsService) {
- $scope.jobObserver = function() {
- return $scope.jobs = JobsService.getJobs('running');
- };
- JobsService.registerObserver($scope.jobObserver);
- $scope.$on('$destroy', function() {
- return JobsService.unRegisterObserver($scope.jobObserver);
- });
- return $scope.jobObserver();
-}]).controller('CompletedJobsController', ["$scope", "$state", "$stateParams", "JobsService", function($scope, $state, $stateParams, JobsService) {
- $scope.jobObserver = function() {
- return $scope.jobs = JobsService.getJobs('finished');
- };
- JobsService.registerObserver($scope.jobObserver);
- $scope.$on('$destroy', function() {
- return JobsService.unRegisterObserver($scope.jobObserver);
- });
- return $scope.jobObserver();
-}]).controller('SingleJobController', ["$scope", "$state", "$stateParams", "JobsService", "MetricsService", "$rootScope", "flinkConfig", "$interval", function($scope, $state, $stateParams, JobsService, MetricsService, $rootScope, flinkConfig, $interval) {
- var refresher;
- $scope.jobid = $stateParams.jobid;
- $scope.job = null;
- $scope.plan = null;
- $scope.vertices = null;
- $scope.backPressureOperatorStats = {};
- JobsService.loadJob($stateParams.jobid).then(function(data) {
- $scope.job = data;
- $scope.plan = data.plan;
- $scope.vertices = data.vertices;
- return MetricsService.setupMetrics($stateParams.jobid, data.vertices);
- });
- refresher = $interval(function() {
- return JobsService.loadJob($stateParams.jobid).then(function(data) {
- $scope.job = data;
- return $scope.$broadcast('reload');
- });
- }, flinkConfig["refresh-interval"]);
- $scope.$on('$destroy', function() {
- $scope.job = null;
- $scope.plan = null;
- $scope.vertices = null;
- $scope.backPressureOperatorStats = null;
- return $interval.cancel(refresher);
- });
- $scope.cancelJob = function(cancelEvent) {
- angular.element(cancelEvent.currentTarget).removeClass("btn").removeClass("btn-default").html('Cancelling...');
- return JobsService.cancelJob($stateParams.jobid).then(function(data) {
- return {};
- });
- };
- return $scope.stopJob = function(stopEvent) {
- angular.element(stopEvent.currentTarget).removeClass("btn").removeClass("btn-default").html('Stopping...');
- return JobsService.stopJob($stateParams.jobid).then(function(data) {
- return {};
- });
- };
-}]).controller('JobPlanController', ["$scope", "$state", "$stateParams", "$window", "JobsService", function($scope, $state, $stateParams, $window, JobsService) {
- $scope.nodeid = null;
- $scope.nodeUnfolded = false;
- $scope.stateList = JobsService.stateList();
- $scope.changeNode = function(nodeid) {
- if (nodeid !== $scope.nodeid) {
- $scope.nodeid = nodeid;
- $scope.vertex = null;
- $scope.subtasks = null;
- $scope.accumulators = null;
- $scope.operatorCheckpointStats = null;
- $scope.$broadcast('reload');
- return $scope.$broadcast('node:change', $scope.nodeid);
- } else {
- $scope.nodeid = null;
- $scope.nodeUnfolded = false;
- $scope.vertex = null;
- $scope.subtasks = null;
- $scope.accumulators = null;
- return $scope.operatorCheckpointStats = null;
- }
- };
- $scope.deactivateNode = function() {
- $scope.nodeid = null;
- $scope.nodeUnfolded = false;
- $scope.vertex = null;
- $scope.subtasks = null;
- $scope.accumulators = null;
- return $scope.operatorCheckpointStats = null;
- };
- return $scope.toggleFold = function() {
- return $scope.nodeUnfolded = !$scope.nodeUnfolded;
- };
-}]).controller('JobPlanSubtasksController', ["$scope", "JobsService", function($scope, JobsService) {
- var getSubtasks;
- getSubtasks = function() {
- return JobsService.getSubtasks($scope.nodeid).then(function(data) {
- return $scope.subtasks = data;
- });
- };
- if ($scope.nodeid && (!$scope.vertex || !$scope.vertex.st)) {
- getSubtasks();
- }
- return $scope.$on('reload', function(event) {
- if ($scope.nodeid) {
- return getSubtasks();
- }
- });
-}]).controller('JobPlanTaskManagersController', ["$scope", "JobsService", function($scope, JobsService) {
- var getTaskManagers;
- getTaskManagers = function() {
- return JobsService.getTaskManagers($scope.nodeid).then(function(data) {
- return $scope.taskmanagers = data;
- });
- };
- if ($scope.nodeid && (!$scope.vertex || !$scope.vertex.st)) {
- getTaskManagers();
- }
- return $scope.$on('reload', function(event) {
- if ($scope.nodeid) {
- return getTaskManagers();
- }
- });
-}]).controller('JobPlanAccumulatorsController', ["$scope", "JobsService", function($scope, JobsService) {
- var getAccumulators;
- getAccumulators = function() {
- return JobsService.getAccumulators($scope.nodeid).then(function(data) {
- $scope.accumulators = data.main;
- return $scope.subtaskAccumulators = data.subtasks;
- });
- };
- if ($scope.nodeid && (!$scope.vertex || !$scope.vertex.accumulators)) {
- getAccumulators();
- }
- return $scope.$on('reload', function(event) {
- if ($scope.nodeid) {
- return getAccumulators();
- }
- });
-}]).controller('JobPlanCheckpointsController', ["$scope", "$state", "$stateParams", "JobsService", function($scope, $state, $stateParams, JobsService) {
- var getGeneralCheckpointStats;
- $scope.checkpointDetails = {};
- $scope.checkpointDetails.id = -1;
- JobsService.getCheckpointConfig().then(function(data) {
- return $scope.checkpointConfig = data;
- });
- getGeneralCheckpointStats = function() {
- return JobsService.getCheckpointStats().then(function(data) {
- if (data !== null) {
- return $scope.checkpointStats = data;
- }
- });
- };
- getGeneralCheckpointStats();
- return $scope.$on('reload', function(event) {
- return getGeneralCheckpointStats();
- });
-}]).controller('JobPlanCheckpointDetailsController', ["$scope", "$state", "$stateParams", "JobsService", function($scope, $state, $stateParams, JobsService) {
- var getCheckpointDetails, getCheckpointSubtaskDetails;
- $scope.subtaskDetails = {};
- $scope.checkpointDetails.id = $stateParams.checkpointId;
- getCheckpointDetails = function(checkpointId) {
- return JobsService.getCheckpointDetails(checkpointId).then(function(data) {
- if (data !== null) {
- return $scope.checkpoint = data;
- } else {
- return $scope.unknown_checkpoint = true;
- }
- });
- };
- getCheckpointSubtaskDetails = function(checkpointId, vertexId) {
- return JobsService.getCheckpointSubtaskDetails(checkpointId, vertexId).then(function(data) {
- if (data !== null) {
- return $scope.subtaskDetails[vertexId] = data;
- }
- });
- };
- getCheckpointDetails($stateParams.checkpointId);
- if ($scope.nodeid) {
- getCheckpointSubtaskDetails($stateParams.checkpointId, $scope.nodeid);
- }
- $scope.$on('reload', function(event) {
- getCheckpointDetails($stateParams.checkpointId);
- if ($scope.nodeid) {
- return getCheckpointSubtaskDetails($stateParams.checkpointId, $scope.nodeid);
- }
- });
- return $scope.$on('$destroy', function() {
- return $scope.checkpointDetails.id = -1;
- });
-}]).controller('JobPlanBackPressureController', ["$scope", "JobsService", function($scope, JobsService) {
- var getOperatorBackPressure;
- getOperatorBackPressure = function() {
- $scope.now = Date.now();
- if ($scope.nodeid) {
- return JobsService.getOperatorBackPressure($scope.nodeid).then(function(data) {
- return $scope.backPressureOperatorStats[$scope.nodeid] = data;
- });
- }
- };
- getOperatorBackPressure();
- return $scope.$on('reload', function(event) {
- return getOperatorBackPressure();
- });
-}]).controller('JobTimelineVertexController', ["$scope", "$state", "$stateParams", "JobsService", function($scope, $state, $stateParams, JobsService) {
- var getVertex;
- getVertex = function() {
- return JobsService.getVertex($stateParams.vertexId).then(function(data) {
- return $scope.vertex = data;
- });
- };
- getVertex();
- return $scope.$on('reload', function(event) {
- return getVertex();
- });
-}]).controller('JobExceptionsController', ["$scope", "$state", "$stateParams", "JobsService", function($scope, $state, $stateParams, JobsService) {
- return JobsService.loadExceptions().then(function(data) {
- return $scope.exceptions = data;
- });
-}]).controller('JobPropertiesController', ["$scope", "JobsService", function($scope, JobsService) {
- return $scope.changeNode = function(nodeid) {
- if (nodeid !== $scope.nodeid) {
- $scope.nodeid = nodeid;
- return JobsService.getNode(nodeid).then(function(data) {
- return $scope.node = data;
- });
- } else {
- $scope.nodeid = null;
- return $scope.node = null;
- }
- };
-}]).controller('JobPlanMetricsController', ["$scope", "JobsService", "MetricsService", function($scope, JobsService, MetricsService) {
- var loadMetrics;
- $scope.dragging = false;
- $scope.window = MetricsService.getWindow();
- $scope.availableMetrics = null;
- $scope.$on('$destroy', function() {
- return MetricsService.unRegisterObserver();
- });
- loadMetrics = function() {
- JobsService.getVertex($scope.nodeid).then(function(data) {
- return $scope.vertex = data;
- });
- return MetricsService.getAvailableMetrics($scope.jobid, $scope.nodeid).then(function(data) {
- $scope.availableMetrics = data;
- $scope.metrics = MetricsService.getMetricsSetup($scope.jobid, $scope.nodeid).names;
- return MetricsService.registerObserver($scope.jobid, $scope.nodeid, function(data) {
- return $scope.$broadcast("metrics:data:update", data.timestamp, data.values);
- });
- });
- };
- $scope.dropped = function(event, index, item, external, type) {
- MetricsService.orderMetrics($scope.jobid, $scope.nodeid, item, index);
- $scope.$broadcast("metrics:refresh", item);
- loadMetrics();
- return false;
- };
- $scope.dragStart = function() {
- return $scope.dragging = true;
- };
- $scope.dragEnd = function() {
- return $scope.dragging = false;
- };
- $scope.addMetric = function(metric) {
- MetricsService.addMetric($scope.jobid, $scope.nodeid, metric.id);
- return loadMetrics();
- };
- $scope.removeMetric = function(metric) {
- MetricsService.removeMetric($scope.jobid, $scope.nodeid, metric);
- return loadMetrics();
- };
- $scope.setMetricSize = function(metric, size) {
- MetricsService.setMetricSize($scope.jobid, $scope.nodeid, metric, size);
- return loadMetrics();
- };
- $scope.getValues = function(metric) {
- return MetricsService.getValues($scope.jobid, $scope.nodeid, metric);
- };
- $scope.$on('node:change', function(event, nodeid) {
- if (!$scope.dragging) {
- return loadMetrics();
- }
- });
- if ($scope.nodeid) {
- return loadMetrics();
- }
-}]);
-
-angular.module('flinkApp').directive('vertex', ["$state", function($state) {
- return {
- template: "<svg class='timeline secondary' width='0' height='0'></svg>",
- scope: {
- data: "="
- },
- link: function(scope, elem, attrs) {
- var analyzeTime, containerW, svgEl;
- svgEl = elem.children()[0];
- containerW = elem.width();
- angular.element(svgEl).attr('width', containerW);
- analyzeTime = function(data) {
- var chart, svg, testData;
- d3.select(svgEl).selectAll("*").remove();
- testData = [];
- angular.forEach(data.subtasks, function(subtask, i) {
- var times;
- times = [
- {
- label: "Scheduled",
- color: "#666",
- borderColor: "#555",
- starting_time: subtask.timestamps["SCHEDULED"],
- ending_time: subtask.timestamps["DEPLOYING"],
- type: 'regular'
- }, {
- label: "Deploying",
- color: "#aaa",
- borderColor: "#555",
- starting_time: subtask.timestamps["DEPLOYING"],
- ending_time: subtask.timestamps["RUNNING"],
- type: 'regular'
- }
- ];
- if (subtask.timestamps["FINISHED"] > 0) {
- times.push({
- label: "Running",
- color: "#ddd",
- borderColor: "#555",
- starting_time: subtask.timestamps["RUNNING"],
- ending_time: subtask.timestamps["FINISHED"],
- type: 'regular'
- });
- }
- return testData.push({
- label: "(" + subtask.subtask + ") " + subtask.host,
- times: times
- });
- });
- chart = d3.timeline().stack().tickFormat({
- format: d3.time.format("%L"),
- tickSize: 1
- }).prefix("single").labelFormat(function(label) {
- return label;
- }).margin({
- left: 100,
- right: 0,
- top: 0,
- bottom: 0
- }).itemHeight(30).relativeTime();
- return svg = d3.select(svgEl).datum(testData).call(chart);
- };
- analyzeTime(scope.data);
- }
- };
-}]).directive('timeline', ["$state", function($state) {
- return {
- template: "<svg class='timeline' width='0' height='0'></svg>",
- scope: {
- vertices: "=",
- jobid: "="
- },
- link: function(scope, elem, attrs) {
- var analyzeTime, containerW, svgEl, translateLabel;
- svgEl = elem.children()[0];
- containerW = elem.width();
- angular.element(svgEl).attr('width', containerW);
- translateLabel = function(label) {
- return label.replace(">", ">");
- };
- analyzeTime = function(data) {
- var chart, svg, testData;
- d3.select(svgEl).selectAll("*").remove();
- testData = [];
- angular.forEach(data, function(vertex) {
- if (vertex['start-time'] > -1) {
- if (vertex.type === 'scheduled') {
- return testData.push({
- times: [
- {
- label: translateLabel(vertex.name),
- color: "#cccccc",
- borderColor: "#555555",
- starting_time: vertex['start-time'],
- ending_time: vertex['end-time'],
- type: vertex.type
- }
- ]
- });
- } else {
- return testData.push({
- times: [
- {
- label: translateLabel(vertex.name),
- color: "#d9f1f7",
- borderColor: "#62cdea",
- starting_time: vertex['start-time'],
- ending_time: vertex['end-time'],
- link: vertex.id,
- type: vertex.type
- }
- ]
- });
- }
- }
- });
- chart = d3.timeline().stack().click(function(d, i, datum) {
- if (d.link) {
- return $state.go("single-job.timeline.vertex", {
- jobid: scope.jobid,
- vertexId: d.link
- });
- }
- }).tickFormat({
- format: d3.time.format("%L"),
- tickSize: 1
- }).prefix("main").margin({
- left: 0,
- right: 0,
- top: 0,
- bottom: 0
- }).itemHeight(30).showBorderLine().showHourTimeline();
- return svg = d3.select(svgEl).datum(testData).call(chart);
- };
- scope.$watch(attrs.vertices, function(data) {
- if (data) {
- return analyzeTime(data);
- }
- });
- }
- };
-}]).directive('split', function() {
- return {
- compile: function(tElem, tAttrs) {
- return Split(tElem.children(), {
- sizes: [50, 50],
- direction: 'vertical'
- });
- }
- };
-}).directive('jobPlan', ["$timeout", function($timeout) {
- return {
- template: "<svg class='graph' width='500' height='400'><g /></svg> <svg class='tmp' width='1' height='1'><g /></svg> <div class='btn-group zoom-buttons'> <a class='btn btn-default zoom-in' ng-click='zoomIn()'><i class='fa fa-plus' /></a> <a class='btn btn-default zoom-out' ng-click='zoomOut()'><i class='fa fa-minus' /></a> </div>",
- scope: {
- plan: '=',
- setNode: '&'
- },
- link: function(scope, elem, attrs) {
- var containerW, createEdge, createLabelEdge, createLabelNode, createNode, d3mainSvg, d3mainSvgG, d3tmpSvg, drawGraph, extendLabelNodeForIteration, g, getNodeType, isSpecialIterationNode, jobid, loadJsonToDagre, mainG, mainSvgElement, mainTmpElement, mainZoom, searchForNode, shortenString, subgraphs;
- g = null;
- mainZoom = d3.behavior.zoom();
- subgraphs = [];
- jobid = attrs.jobid;
- mainSvgElement = elem.children()[0];
- mainG = elem.children().children()[0];
- mainTmpElement = elem.children()[1];
- d3mainSvg = d3.select(mainSvgElement);
- d3mainSvgG = d3.select(mainG);
- d3tmpSvg = d3.select(mainTmpElement);
- containerW = elem.width();
- angular.element(elem.children()[0]).width(containerW);
- scope.zoomIn = function() {
- var translate, v1, v2;
- if (mainZoom.scale() < 2.99) {
- translate = mainZoom.translate();
- v1 = translate[0] * (mainZoom.scale() + 0.1 / (mainZoom.scale()));
- v2 = translate[1] * (mainZoom.scale() + 0.1 / (mainZoom.scale()));
- mainZoom.scale(mainZoom.scale() + 0.1);
- mainZoom.translate([v1, v2]);
- return d3mainSvgG.attr("transform", "translate(" + v1 + "," + v2 + ") scale(" + mainZoom.scale() + ")");
- }
- };
- scope.zoomOut = function() {
- var translate, v1, v2;
- if (mainZoom.scale() > 0.31) {
- mainZoom.scale(mainZoom.scale() - 0.1);
- translate = mainZoom.translate();
- v1 = translate[0] * (mainZoom.scale() - 0.1 / (mainZoom.scale()));
- v2 = translate[1] * (mainZoom.scale() - 0.1 / (mainZoom.scale()));
- mainZoom.translate([v1, v2]);
- return d3mainSvgG.attr("transform", "translate(" + v1 + "," + v2 + ") scale(" + mainZoom.scale() + ")");
- }
- };
- createLabelEdge = function(el) {
- var labelValue;
- labelValue = "";
- if ((el.ship_strategy != null) || (el.local_strategy != null)) {
- labelValue += "<div class='edge-label'>";
- if (el.ship_strategy != null) {
- labelValue += el.ship_strategy;
- }
- if (el.temp_mode !== undefined) {
- labelValue += " (" + el.temp_mode + ")";
- }
- if (el.local_strategy !== undefined) {
- labelValue += ",<br>" + el.local_strategy;
- }
- labelValue += "</div>";
- }
- return labelValue;
- };
- isSpecialIterationNode = function(info) {
- return info === "partialSolution" || info === "nextPartialSolution" || info === "workset" || info === "nextWorkset" || info === "solutionSet" || info === "solutionDelta";
- };
- getNodeType = function(el, info) {
- if (info === "mirror") {
- return 'node-mirror';
- } else if (isSpecialIterationNode(info)) {
- return 'node-iteration';
- } else {
- return 'node-normal';
- }
- };
- createLabelNode = function(el, info, maxW, maxH) {
- var labelValue, stepName;
- labelValue = "<div href='#/jobs/" + jobid + "/vertex/" + el.id + "' class='node-label " + getNodeType(el, info) + "'>";
- if (info === "mirror") {
- labelValue += "<h3 class='node-name'>Mirror of " + el.operator + "</h3>";
- } else {
- labelValue += "<h3 class='node-name'>" + el.operator + "</h3>";
- }
- if (el.description === "") {
- labelValue += "";
- } else {
- stepName = el.description;
- stepName = shortenString(stepName);
- labelValue += "<h4 class='step-name'>" + stepName + "</h4>";
- }
- if (el.step_function != null) {
- labelValue += extendLabelNodeForIteration(el.id, maxW, maxH);
- } else {
- if (isSpecialIterationNode(info)) {
- labelValue += "<h5>" + info + " Node</h5>";
- }
- if (el.parallelism !== "") {
- labelValue += "<h5>Parallelism: " + el.parallelism + "</h5>";
- }
- if (!(el.operator === undefined || !el.operator_strategy)) {
- labelValue += "<h5>Operation: " + shortenString(el.operator_strategy) + "</h5>";
- }
- }
- labelValue += "</div>";
- return labelValue;
- };
- extendLabelNodeForIteration = function(id, maxW, maxH) {
- var labelValue, svgID;
- svgID = "svg-" + id;
- labelValue = "<svg class='" + svgID + "' width=" + maxW + " height=" + maxH + "><g /></svg>";
- return labelValue;
- };
- shortenString = function(s) {
- var sbr;
- if (s.charAt(0) === "<") {
- s = s.replace("<", "<");
- s = s.replace(">", ">");
- }
- sbr = "";
- while (s.length > 30) {
- sbr = sbr + s.substring(0, 30) + "<br>";
- s = s.substring(30, s.length);
- }
- sbr = sbr + s;
- return sbr;
- };
- createNode = function(g, data, el, isParent, maxW, maxH) {
- if (isParent == null) {
- isParent = false;
- }
- if (el.id === data.partial_solution) {
- return g.setNode(el.id, {
- label: createLabelNode(el, "partialSolution", maxW, maxH),
- labelType: 'html',
- "class": getNodeType(el, "partialSolution")
- });
- } else if (el.id === data.next_partial_solution) {
- return g.setNode(el.id, {
- label: createLabelNode(el, "nextPartialSolution", maxW, maxH),
- labelType: 'html',
- "class": getNodeType(el, "nextPartialSolution")
- });
- } else if (el.id === data.workset) {
- return g.setNode(el.id, {
- label: createLabelNode(el, "workset", maxW, maxH),
- labelType: 'html',
- "class": getNodeType(el, "workset")
- });
- } else if (el.id === data.next_workset) {
- return g.setNode(el.id, {
- label: createLabelNode(el, "nextWorkset", maxW, maxH),
- labelType: 'html',
- "class": getNodeType(el, "nextWorkset")
- });
- } else if (el.id === data.solution_set) {
- return g.setNode(el.id, {
- label: createLabelNode(el, "solutionSet", maxW, maxH),
- labelType: 'html',
- "class": getNodeType(el, "solutionSet")
- });
- } else if (el.id === data.solution_delta) {
- return g.setNode(el.id, {
- label: createLabelNode(el, "solutionDelta", maxW, maxH),
- labelType: 'html',
- "class": getNodeType(el, "solutionDelta")
- });
- } else {
- return g.setNode(el.id, {
- label: createLabelNode(el, "", maxW, maxH),
- labelType: 'html',
- "class": getNodeType(el, "")
- });
- }
- };
- createEdge = function(g, data, el, existingNodes, pred) {
- return g.setEdge(pred.id, el.id, {
- label: createLabelEdge(pred),
- labelType: 'html',
- arrowhead: 'normal'
- });
- };
- loadJsonToDagre = function(g, data) {
- var el, existingNodes, isParent, k, l, len, len1, maxH, maxW, pred, r, ref, sg, toIterate;
- existingNodes = [];
- if (data.nodes != null) {
- toIterate = data.nodes;
- } else {
- toIterate = data.step_function;
- isParent = true;
- }
- for (k = 0, len = toIterate.length; k < len; k++) {
- el = toIterate[k];
- maxW = 0;
- maxH = 0;
- if (el.step_function) {
- sg = new dagreD3.graphlib.Graph({
- multigraph: true,
- compound: true
- }).setGraph({
- nodesep: 20,
- edgesep: 0,
- ranksep: 20,
- rankdir: "LR",
- marginx: 10,
- marginy: 10
- });
- subgraphs[el.id] = sg;
- loadJsonToDagre(sg, el);
- r = new dagreD3.render();
- d3tmpSvg.select('g').call(r, sg);
- maxW = sg.graph().width;
- maxH = sg.graph().height;
- angular.element(mainTmpElement).empty();
- }
- createNode(g, data, el, isParent, maxW, maxH);
- existingNodes.push(el.id);
- if (el.inputs != null) {
- ref = el.inputs;
- for (l = 0, len1 = ref.length; l < len1; l++) {
- pred = ref[l];
- createEdge(g, data, el, existingNodes, pred);
- }
- }
- }
- return g;
- };
- searchForNode = function(data, nodeID) {
- var el, i, j;
- for (i in data.nodes) {
- el = data.nodes[i];
- if (el.id === nodeID) {
- return el;
- }
- if (el.step_function != null) {
- for (j in el.step_function) {
- if (el.step_function[j].id === nodeID) {
- return el.step_function[j];
- }
- }
- }
- }
- };
- drawGraph = function(data) {
- var i, newScale, renderer, sg, xCenterOffset, yCenterOffset;
- g = new dagreD3.graphlib.Graph({
- multigraph: true,
- compound: true
- }).setGraph({
- nodesep: 70,
- edgesep: 0,
- ranksep: 50,
- rankdir: "LR",
- marginx: 40,
- marginy: 40
- });
- loadJsonToDagre(g, data);
- renderer = new dagreD3.render();
- d3mainSvgG.call(renderer, g);
- for (i in subgraphs) {
- sg = subgraphs[i];
- d3mainSvg.select('svg.svg-' + i + ' g').call(renderer, sg);
- }
- newScale = 0.5;
- xCenterOffset = Math.floor((angular.element(mainSvgElement).width() - g.graph().width * newScale) / 2);
- yCenterOffset = Math.floor((angular.element(mainSvgElement).height() - g.graph().height * newScale) / 2);
- mainZoom.scale(newScale).translate([xCenterOffset, yCenterOffset]);
- d3mainSvgG.attr("transform", "translate(" + xCenterOffset + ", " + yCenterOffset + ") scale(" + mainZoom.scale() + ")");
- mainZoom.on("zoom", function() {
- var ev;
- ev = d3.event;
- return d3mainSvgG.attr("transform", "translate(" + ev.translate + ") scale(" + ev.scale + ")");
- });
- mainZoom(d3mainSvg);
- return d3mainSvgG.selectAll('.node').on('click', function(d) {
- return scope.setNode({
- nodeid: d
- });
- });
- };
- scope.$watch(attrs.plan, function(newPlan) {
- if (newPlan) {
- return drawGraph(newPlan);
- }
- });
- }
- };
-}]);
-
-angular.module('flinkApp').service('JobsService', ["$http", "flinkConfig", "$log", "amMoment", "$q", "$timeout", function($http, flinkConfig, $log, amMoment, $q, $timeout) {
- var currentJob, currentPlan, deferreds, jobObservers, jobs, notifyObservers;
- currentJob = null;
- currentPlan = null;
- deferreds = {};
- jobs = {
- running: [],
- finished: [],
- cancelled: [],
- failed: []
- };
- jobObservers = [];
- notifyObservers = function() {
- return angular.forEach(jobObservers, function(callback) {
- return callback();
- });
- };
- this.registerObserver = function(callback) {
- return jobObservers.push(callback);
- };
- this.unRegisterObserver = function(callback) {
- var index;
- index = jobObservers.indexOf(callback);
- return jobObservers.splice(index, 1);
- };
- this.stateList = function() {
- return ['SCHEDULED', 'DEPLOYING', 'RUNNING', 'FINISHED', 'FAILED', 'CANCELING', 'CANCELED'];
- };
- this.translateLabelState = function(state) {
- switch (state.toLowerCase()) {
- case 'finished':
- return 'success';
- case 'failed':
- return 'danger';
- case 'scheduled':
- return 'default';
- case 'deploying':
- return 'info';
- case 'running':
- return 'primary';
- case 'canceling':
- return 'warning';
- case 'pending':
- return 'info';
- case 'total':
- return 'black';
- default:
- return 'default';
- }
- };
- this.setEndTimes = function(list) {
- return angular.forEach(list, function(item, jobKey) {
- if (!(item['end-time'] > -1)) {
- return item['end-time'] = item['start-time'] + item['duration'];
- }
- });
- };
- this.processVertices = function(data) {
- angular.forEach(data.vertices, function(vertex, i) {
- return vertex.type = 'regular';
- });
- return data.vertices.unshift({
- name: 'Scheduled',
- 'start-time': data.timestamps['CREATED'],
- 'end-time': data.timestamps['CREATED'] + 1,
- type: 'scheduled'
- });
- };
- this.listJobs = function() {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "joboverview").success((function(_this) {
- return function(data, status, headers, config) {
- angular.forEach(data, function(list, listKey) {
- switch (listKey) {
- case 'running':
- return jobs.running = _this.setEndTimes(list);
- case 'finished':
- return jobs.finished = _this.setEndTimes(list);
- case 'cancelled':
- return jobs.cancelled = _this.setEndTimes(list);
- case 'failed':
- return jobs.failed = _this.setEndTimes(list);
- }
- });
- deferred.resolve(jobs);
- return notifyObservers();
- };
- })(this));
- return deferred.promise;
- };
- this.getJobs = function(type) {
- return jobs[type];
- };
- this.getAllJobs = function() {
- return jobs;
- };
- this.loadJob = function(jobid) {
- currentJob = null;
- deferreds.job = $q.defer();
- $http.get(flinkConfig.jobServer + "jobs/" + jobid).success((function(_this) {
- return function(data, status, headers, config) {
- _this.setEndTimes(data.vertices);
- _this.processVertices(data);
- return $http.get(flinkConfig.jobServer + "jobs/" + jobid + "/config").success(function(jobConfig) {
- data = angular.extend(data, jobConfig);
- currentJob = data;
- return deferreds.job.resolve(currentJob);
- });
- };
- })(this));
- return deferreds.job.promise;
- };
- this.getNode = function(nodeid) {
- var deferred, seekNode;
- seekNode = function(nodeid, data) {
- var j, len, node, sub;
- for (j = 0, len = data.length; j < len; j++) {
- node = data[j];
- if (node.id === nodeid) {
- return node;
- }
- if (node.step_function) {
- sub = seekNode(nodeid, node.step_function);
- }
- if (sub) {
- return sub;
- }
- }
- return null;
- };
- deferred = $q.defer();
- deferreds.job.promise.then((function(_this) {
- return function(data) {
- var foundNode;
- foundNode = seekNode(nodeid, currentJob.plan.nodes);
- foundNode.vertex = _this.seekVertex(nodeid);
- return deferred.resolve(foundNode);
- };
- })(this));
- return deferred.promise;
- };
- this.seekVertex = function(nodeid) {
- var j, len, ref, vertex;
- ref = currentJob.vertices;
- for (j = 0, len = ref.length; j < len; j++) {
- vertex = ref[j];
- if (vertex.id === nodeid) {
- return vertex;
- }
- }
- return null;
- };
- this.getVertex = function(vertexid) {
- var deferred;
- deferred = $q.defer();
- deferreds.job.promise.then((function(_this) {
- return function(data) {
- var vertex;
- vertex = _this.seekVertex(vertexid);
- return $http.get(flinkConfig.jobServer + "jobs/" + currentJob.jid + "/vertices/" + vertexid + "/subtasktimes").success(function(data) {
- vertex.subtasks = data.subtasks;
- return deferred.resolve(vertex);
- });
- };
- })(this));
- return deferred.promise;
- };
- this.getSubtasks = function(vertexid) {
- var deferred;
- deferred = $q.defer();
- deferreds.job.promise.then((function(_this) {
- return function(data) {
- return $http.get(flinkConfig.jobServer + "jobs/" + currentJob.jid + "/vertices/" + vertexid).success(function(data) {
- var subtasks;
- subtasks = data.subtasks;
- return deferred.resolve(subtasks);
- });
- };
- })(this));
- return deferred.promise;
- };
- this.getTaskManagers = function(vertexid) {
- var deferred;
- deferred = $q.defer();
- deferreds.job.promise.then((function(_this) {
- return function(data) {
- return $http.get(flinkConfig.jobServer + "jobs/" + currentJob.jid + "/vertices/" + vertexid + "/taskmanagers").success(function(data) {
- var taskmanagers;
- taskmanagers = data.taskmanagers;
- return deferred.resolve(taskmanagers);
- });
- };
- })(this));
- return deferred.promise;
- };
- this.getAccumulators = function(vertexid) {
- var deferred;
- deferred = $q.defer();
- deferreds.job.promise.then((function(_this) {
- return function(data) {
- console.log(currentJob.jid);
- return $http.get(flinkConfig.jobServer + "jobs/" + currentJob.jid + "/vertices/" + vertexid + "/accumulators").success(function(data) {
- var accumulators;
- accumulators = data['user-accumulators'];
- return $http.get(flinkConfig.jobServer + "jobs/" + currentJob.jid + "/vertices/" + vertexid + "/subtasks/accumulators").success(function(data) {
- var subtaskAccumulators;
- subtaskAccumulators = data.subtasks;
- return deferred.resolve({
- main: accumulators,
- subtasks: subtaskAccumulators
- });
- });
- });
- };
- })(this));
- return deferred.promise;
- };
- this.getCheckpointConfig = function() {
- var deferred;
- deferred = $q.defer();
- deferreds.job.promise.then((function(_this) {
- return function(data) {
- return $http.get(flinkConfig.jobServer + "jobs/" + currentJob.jid + "/checkpoints/config").success(function(data) {
- if (angular.equals({}, data)) {
- return deferred.resolve(null);
- } else {
- return deferred.resolve(data);
- }
- });
- };
- })(this));
- return deferred.promise;
- };
- this.getCheckpointStats = function() {
- var deferred;
- deferred = $q.defer();
- deferreds.job.promise.then((function(_this) {
- return function(data) {
- return $http.get(flinkConfig.jobServer + "jobs/" + currentJob.jid + "/checkpoints").success(function(data, status, headers, config) {
- if (angular.equals({}, data)) {
- return deferred.resolve(null);
- } else {
- return deferred.resolve(data);
- }
- });
- };
- })(this));
- return deferred.promise;
- };
- this.getCheckpointDetails = function(checkpointid) {
- var deferred;
- deferred = $q.defer();
- deferreds.job.promise.then((function(_this) {
- return function(data) {
- return $http.get(flinkConfig.jobServer + "jobs/" + currentJob.jid + "/checkpoints/details/" + checkpointid).success(function(data) {
- if (angular.equals({}, data)) {
- return deferred.resolve(null);
- } else {
- return deferred.resolve(data);
- }
- });
- };
- })(this));
- return deferred.promise;
- };
- this.getCheckpointSubtaskDetails = function(checkpointid, vertexid) {
- var deferred;
- deferred = $q.defer();
- deferreds.job.promise.then((function(_this) {
- return function(data) {
- return $http.get(flinkConfig.jobServer + "jobs/" + currentJob.jid + "/checkpoints/details/" + checkpointid + "/subtasks/" + vertexid).success(function(data) {
- if (angular.equals({}, data)) {
- return deferred.resolve(null);
- } else {
- return deferred.resolve(data);
- }
- });
- };
- })(this));
- return deferred.promise;
- };
- this.getOperatorBackPressure = function(vertexid) {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "jobs/" + currentJob.jid + "/vertices/" + vertexid + "/backpressure").success((function(_this) {
- return function(data) {
- return deferred.resolve(data);
- };
- })(this));
- return deferred.promise;
- };
- this.translateBackPressureLabelState = function(state) {
- switch (state.toLowerCase()) {
- case 'in-progress':
- return 'danger';
- case 'ok':
- return 'success';
- case 'low':
- return 'warning';
- case 'high':
- return 'danger';
- default:
- return 'default';
- }
- };
- this.loadExceptions = function() {
- var deferred;
- deferred = $q.defer();
- deferreds.job.promise.then((function(_this) {
- return function(data) {
- return $http.get(flinkConfig.jobServer + "jobs/" + currentJob.jid + "/exceptions").success(function(exceptions) {
- currentJob.exceptions = exceptions;
- return deferred.resolve(exceptions);
- });
- };
- })(this));
- return deferred.promise;
- };
- this.cancelJob = function(jobid) {
- return $http.get(flinkConfig.jobServer + "jobs/" + jobid + "/yarn-cancel");
- };
- this.stopJob = function(jobid) {
- return $http.get("jobs/" + jobid + "/yarn-stop");
- };
- return this;
-}]);
-
-angular.module('flinkApp').directive('metricsGraph', function() {
- return {
- template: '<div class="panel panel-default panel-metric"> <div class="panel-heading"> <span class="metric-title">{{metric.id}}</span> <div class="buttons"> <div class="btn-group"> <button type="button" ng-class="[btnClasses, {active: metric.size != \'big\'}]" ng-click="setSize(\'small\')">Small</button> <button type="button" ng-class="[btnClasses, {active: metric.size == \'big\'}]" ng-click="setSize(\'big\')">Big</button> </div> <a title="Remove" class="btn btn-default btn-xs remove" ng-click="removeMetric()"><i class="fa fa-close" /></a> </div> </div> <div class="panel-body"> <svg /> </div> </div>',
- replace: true,
- scope: {
- metric: "=",
- window: "=",
- removeMetric: "&",
- setMetricSize: "=",
- getValues: "&"
- },
- link: function(scope, element, attrs) {
- scope.btnClasses = ['btn', 'btn-default', 'btn-xs'];
- scope.value = null;
- scope.data = [
- {
- values: scope.getValues()
- }
- ];
- scope.options = {
- x: function(d, i) {
- return d.x;
- },
- y: function(d, i) {
- return d.y;
- },
- xTickFormat: function(d) {
- return d3.time.format('%H:%M:%S')(new Date(d));
- },
- yTickFormat: function(d) {
- var absD, found, pow, step;
- found = false;
- pow = 0;
- step = 1;
- absD = Math.abs(d);
- while (!found && pow < 50) {
- if (Math.pow(10, pow) <= absD && absD < Math.pow(10, pow + step)) {
- found = true;
- } else {
- pow += step;
- }
- }
- if (found && pow > 6) {
- return (d / Math.pow(10, pow)) + "E" + pow;
- } else {
- return "" + d;
- }
- }
- };
- scope.showChart = function() {
- return d3.select(element.find("svg")[0]).datum(scope.data).transition().duration(250).call(scope.chart);
- };
- scope.chart = nv.models.lineChart().options(scope.options).showLegend(false).margin({
- top: 15,
- left: 60,
- bottom: 30,
- right: 30
- });
- scope.chart.yAxis.showMaxMin(false);
- scope.chart.tooltip.hideDelay(0);
- scope.chart.tooltip.contentGenerator(function(obj) {
- return "<p>" + (d3.time.format('%H:%M:%S')(new Date(obj.point.x))) + " | " + obj.point.y + "</p>";
- });
- nv.utils.windowResize(scope.chart.update);
- scope.setSize = function(size) {
- return scope.setMetricSize(scope.metric, size);
- };
- scope.showChart();
- scope.$on('metrics:data:update', function(event, timestamp, data) {
- scope.value = parseFloat(data[scope.metric.id]);
- scope.data[0].values.push({
- x: timestamp,
- y: scope.value
- });
- if (scope.data[0].values.length > scope.window) {
- scope.data[0].values.shift();
- }
- scope.showChart();
- scope.chart.clearHighlights();
- return scope.chart.tooltip.hidden(true);
- });
- return element.find(".metric-title").qtip({
- content: {
- text: scope.metric.id
- },
- position: {
- my: 'bottom left',
- at: 'top left'
- },
- style: {
- classes: 'qtip-light qtip-timeline-bar'
- }
- });
- }
- };
-});
-
-angular.module('flinkApp').service('MetricsService', ["$http", "$q", "flinkConfig", "$interval", function($http, $q, flinkConfig, $interval) {
- this.metrics = {};
- this.values = {};
- this.watched = {};
- this.observer = {
- jobid: null,
- nodeid: null,
- callback: null
- };
- this.refresh = $interval((function(_this) {
- return function() {
- return angular.forEach(_this.metrics, function(vertices, jobid) {
- return angular.forEach(vertices, function(metrics, nodeid) {
- var names;
- names = [];
- angular.forEach(metrics, function(metric, index) {
- return names.push(metric.id);
- });
- if (names.length > 0) {
- return _this.getMetrics(jobid, nodeid, names).then(function(values) {
- if (jobid === _this.observer.jobid && nodeid === _this.observer.nodeid) {
- if (_this.observer.callback) {
- return _this.observer.callback(values);
- }
- }
- });
- }
- });
- });
- };
- })(this), flinkConfig["refresh-interval"]);
- this.registerObserver = function(jobid, nodeid, callback) {
- this.observer.jobid = jobid;
- this.observer.nodeid = nodeid;
- return this.observer.callback = callback;
- };
- this.unRegisterObserver = function() {
- return this.observer = {
- jobid: null,
- nodeid: null,
- callback: null
- };
- };
- this.setupMetrics = function(jobid, vertices) {
- this.setupLS();
- this.watched[jobid] = [];
- return angular.forEach(vertices, (function(_this) {
- return function(v, k) {
- if (v.id) {
- return _this.watched[jobid].push(v.id);
- }
- };
- })(this));
- };
- this.getWindow = function() {
- return 100;
- };
- this.setupLS = function() {
- if (localStorage.flinkMetrics == null) {
- this.saveSetup();
- }
- return this.metrics = JSON.parse(localStorage.flinkMetrics);
- };
- this.saveSetup = function() {
- return localStorage.flinkMetrics = JSON.stringify(this.metrics);
- };
- this.saveValue = function(jobid, nodeid, value) {
- if (this.values[jobid] == null) {
- this.values[jobid] = {};
- }
- if (this.values[jobid][nodeid] == null) {
- this.values[jobid][nodeid] = [];
- }
- this.values[jobid][nodeid].push(value);
- if (this.values[jobid][nodeid].length > this.getWindow()) {
- return this.values[jobid][nodeid].shift();
- }
- };
- this.getValues = function(jobid, nodeid, metricid) {
- var results;
- if (this.values[jobid] == null) {
- return [];
- }
- if (this.values[jobid][nodeid] == null) {
- return [];
- }
- results = [];
- angular.forEach(this.values[jobid][nodeid], (function(_this) {
- return function(v, k) {
- if (v.values[metricid] != null) {
- return results.push({
- x: v.timestamp,
- y: v.values[metricid]
- });
- }
- };
- })(this));
- return results;
- };
- this.setupLSFor = function(jobid, nodeid) {
- if (this.metrics[jobid] == null) {
- this.metrics[jobid] = {};
- }
- if (this.metrics[jobid][nodeid] == null) {
- return this.metrics[jobid][nodeid] = [];
- }
- };
- this.addMetric = function(jobid, nodeid, metricid) {
- this.setupLSFor(jobid, nodeid);
- this.metrics[jobid][nodeid].push({
- id: metricid,
- size: 'small'
- });
- return this.saveSetup();
- };
- this.removeMetric = (function(_this) {
- return function(jobid, nodeid, metric) {
- var i;
- if (_this.metrics[jobid][nodeid] != null) {
- i = _this.metrics[jobid][nodeid].indexOf(metric);
- if (i === -1) {
- i = _.findIndex(_this.metrics[jobid][nodeid], {
- id: metric
- });
- }
- if (i !== -1) {
- _this.metrics[jobid][nodeid].splice(i, 1);
- }
- return _this.saveSetup();
- }
- };
- })(this);
- this.setMetricSize = (function(_this) {
- return function(jobid, nodeid, metric, size) {
- var i;
- if (_this.metrics[jobid][nodeid] != null) {
- i = _this.metrics[jobid][nodeid].indexOf(metric.id);
- if (i === -1) {
- i = _.findIndex(_this.metrics[jobid][nodeid], {
- id: metric.id
- });
- }
- if (i !== -1) {
- _this.metrics[jobid][nodeid][i] = {
- id: metric.id,
- size: size
- };
- }
- return _this.saveSetup();
- }
- };
- })(this);
- this.orderMetrics = function(jobid, nodeid, item, index) {
- this.setupLSFor(jobid, nodeid);
- angular.forEach(this.metrics[jobid][nodeid], (function(_this) {
- return function(v, k) {
- if (v.id === item.id) {
- _this.metrics[jobid][nodeid].splice(k, 1);
- if (k < index) {
- return index = index - 1;
- }
- }
- };
- })(this));
- this.metrics[jobid][nodeid].splice(index, 0, item);
- return this.saveSetup();
- };
- this.getMetricsSetup = (function(_this) {
- return function(jobid, nodeid) {
- return {
- names: _.map(_this.metrics[jobid][nodeid], function(value) {
- if (_.isString(value)) {
- return {
- id: value,
- size: "small"
- };
- } else {
- return value;
- }
- })
- };
- };
- })(this);
- this.getAvailableMetrics = (function(_this) {
- return function(jobid, nodeid) {
- var deferred;
- _this.setupLSFor(jobid, nodeid);
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "jobs/" + jobid + "/vertices/" + nodeid + "/metrics").success(function(data) {
- var results;
- results = [];
- angular.forEach(data, function(v, k) {
- var i;
- i = _this.metrics[jobid][nodeid].indexOf(v.id);
- if (i === -1) {
- i = _.findIndex(_this.metrics[jobid][nodeid], {
- id: v.id
- });
- }
- if (i === -1) {
- return results.push(v);
- }
- });
- return deferred.resolve(results);
- });
- return deferred.promise;
- };
- })(this);
- this.getAllAvailableMetrics = (function(_this) {
- return function(jobid, nodeid) {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "jobs/" + jobid + "/vertices/" + nodeid + "/metrics").success(function(data) {
- return deferred.resolve(data);
- });
- return deferred.promise;
- };
- })(this);
- this.getMetrics = function(jobid, nodeid, metricIds) {
- var deferred, ids;
- deferred = $q.defer();
- ids = metricIds.join(",");
- $http.get(flinkConfig.jobServer + "jobs/" + jobid + "/vertices/" + nodeid + "/metrics?get=" + ids).success((function(_this) {
- return function(data) {
- var newValue, result;
- result = {};
- angular.forEach(data, function(v, k) {
- return result[v.id] = parseInt(v.value);
- });
- newValue = {
- timestamp: Date.now(),
- values: result
- };
- _this.saveValue(jobid, nodeid, newValue);
- return deferred.resolve(newValue);
- };
- })(this));
- return deferred.promise;
- };
- this.setupLS();
- return this;
-}]);
-
-angular.module('flinkApp').controller('JobSubmitController', ["$scope", "JobSubmitService", "$interval", "flinkConfig", "$state", "$location", function($scope, JobSubmitService, $interval, flinkConfig, $state, $location) {
- var refresh;
- $scope.yarn = $location.absUrl().indexOf("/proxy/application_") !== -1;
- $scope.loadList = function() {
- return JobSubmitService.loadJarList().then(function(data) {
- $scope.address = data.address;
- $scope.noaccess = data.error;
- return $scope.jars = data.files;
- });
- };
- $scope.defaultState = function() {
- $scope.plan = null;
- $scope.error = null;
- return $scope.state = {
- selected: null,
- parallelism: "",
- savepointPath: "",
- allowNonRestoredState: false,
- 'entry-class': "",
- 'program-args': "",
- 'plan-button': "Show Plan",
- 'submit-button': "Submit",
- 'action-time': 0
- };
- };
- $scope.defaultState();
- $scope.uploader = {};
- $scope.loadList();
- refresh = $interval(function() {
- return $scope.loadList();
- }, flinkConfig["refresh-interval"]);
- $scope.$on('$destroy', function() {
- return $interval.cancel(refresh);
- });
- $scope.selectJar = function(id) {
- if ($scope.state.selected === id) {
- return $scope.defaultState();
- } else {
- $scope.defaultState();
- return $scope.state.selected = id;
- }
- };
- $scope.deleteJar = function(event, id) {
- if ($scope.state.selected === id) {
- $scope.defaultState();
- }
- angular.element(event.currentTarget).removeClass("fa-remove").addClass("fa-spin fa-spinner");
- return JobSubmitService.deleteJar(id).then(function(data) {
- angular.element(event.currentTarget).removeClass("fa-spin fa-spinner").addClass("fa-remove");
- if (data.error != null) {
- return alert(data.error);
- }
- });
- };
- $scope.loadEntryClass = function(name) {
- return $scope.state['entry-class'] = name;
- };
- $scope.getPlan = function() {
- var action;
- if ($scope.state['plan-button'] === "Show Plan") {
- action = new Date().getTime();
- $scope.state['action-time'] = action;
- $scope.state['submit-button'] = "Submit";
- $scope.state['plan-button'] = "Getting Plan";
- $scope.error = null;
- $scope.plan = null;
- return JobSubmitService.getPlan($scope.state.selected, {
- 'entry-class': $scope.state['entry-class'],
- parallelism: $scope.state.parallelism,
- 'program-args': $scope.state['program-args']
- }).then(function(data) {
- if (action === $scope.state['action-time']) {
- $scope.state['plan-button'] = "Show Plan";
- $scope.error = data.error;
- return $scope.plan = data.plan;
- }
- });
- }
- };
- $scope.runJob = function() {
- var action;
- if ($scope.state['submit-button'] === "Submit") {
- action = new Date().getTime();
- $scope.state['action-time'] = action;
- $scope.state['submit-button'] = "Submitting";
- $scope.state['plan-button'] = "Show Plan";
- $scope.error = null;
- return JobSubmitService.runJob($scope.state.selected, {
- 'entry-class': $scope.state['entry-class'],
- parallelism: $scope.state.parallelism,
- 'program-args': $scope.state['program-args'],
- savepointPath: $scope.state['savepointPath'],
- allowNonRestoredState: $scope.state['allowNonRestoredState']
- }).then(function(data) {
- if (action === $scope.state['action-time']) {
- $scope.state['submit-button'] = "Submit";
- $scope.error = data.error;
- if (data.jobid != null) {
- return $state.go("single-job.plan.subtasks", {
- jobid: data.jobid
- });
- }
- }
- });
- }
- };
- $scope.nodeid = null;
- $scope.changeNode = function(nodeid) {
- if (nodeid !== $scope.nodeid) {
- $scope.nodeid = nodeid;
- $scope.vertex = null;
- $scope.subtasks = null;
- $scope.accumulators = null;
- return $scope.$broadcast('reload');
- } else {
- $scope.nodeid = null;
- $scope.nodeUnfolded = false;
- $scope.vertex = null;
- $scope.subtasks = null;
- return $scope.accumulators = null;
- }
- };
- $scope.clearFiles = function() {
- return $scope.uploader = {};
- };
- $scope.uploadFiles = function(files) {
- $scope.uploader = {};
- if (files.length === 1) {
- $scope.uploader['file'] = files[0];
- return $scope.uploader['upload'] = true;
- } else {
- return $scope.uploader['error'] = "Did ya forget to select a file?";
- }
- };
- return $scope.startUpload = function() {
- var formdata, xhr;
- if ($scope.uploader['file'] != null) {
- formdata = new FormData();
- formdata.append("jarfile", $scope.uploader['file']);
- $scope.uploader['upload'] = false;
- $scope.uploader['success'] = "Initializing upload...";
- xhr = new XMLHttpRequest();
- xhr.upload.onprogress = function(event) {
- $scope.uploader['success'] = null;
- return $scope.uploader['progress'] = parseInt(100 * event.loaded / event.total);
- };
- xhr.upload.onerror = function(event) {
- $scope.uploader['progress'] = null;
- return $scope.uploader['error'] = "An error occurred while uploading your file";
- };
- xhr.upload.onload = function(event) {
- $scope.uploader['progress'] = null;
- return $scope.uploader['success'] = "Saving...";
- };
- xhr.onreadystatechange = function() {
- var response;
- if (xhr.readyState === 4) {
- response = JSON.parse(xhr.responseText);
- if (response.error != null) {
- $scope.uploader['error'] = response.error;
- return $scope.uploader['success'] = null;
- } else {
- return $scope.uploader['success'] = "Uploaded!";
- }
- }
- };
- xhr.open("POST", "/jars/upload");
- return xhr.send(formdata);
- } else {
- return console.log("Unexpected Error. This should not happen");
- }
- };
-}]).filter('getJarSelectClass', function() {
- return function(selected, actual) {
- if (selected === actual) {
- return "fa-check-square";
- } else {
- return "fa-square-o";
- }
- };
-});
-
-angular.module('flinkApp').service('JobSubmitService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
- this.loadJarList = function() {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "jars/").success(function(data, status, headers, config) {
- return deferred.resolve(data);
- });
- return deferred.promise;
- };
- this.deleteJar = function(id) {
- var deferred;
- deferred = $q.defer();
- $http["delete"](flinkConfig.jobServer + "jars/" + encodeURIComponent(id)).success(function(data, status, headers, config) {
- return deferred.resolve(data);
- });
- return deferred.promise;
- };
- this.getPlan = function(id, args) {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "jars/" + encodeURIComponent(id) + "/plan", {
- params: args
- }).success(function(data, status, headers, config) {
- return deferred.resolve(data);
- });
- return deferred.promise;
- };
- this.runJob = function(id, args) {
- var deferred;
- deferred = $q.defer();
- $http.post(flinkConfig.jobServer + "jars/" + encodeURIComponent(id) + "/run", {}, {
- params: args
- }).success(function(data, status, headers, config) {
- return deferred.resolve(data);
- });
- return deferred.promise;
- };
- return this;
-}]);
-
-angular.module('flinkApp').controller('AllTaskManagersController', ["$scope", "TaskManagersService", "$interval", "flinkConfig", function($scope, TaskManagersService, $interval, flinkConfig) {
- var refresh;
- TaskManagersService.loadManagers().then(function(data) {
- return $scope.managers = data;
- });
- refresh = $interval(function() {
- return TaskManagersService.loadManagers().then(function(data) {
- return $scope.managers = data;
- });
- }, flinkConfig["refresh-interval"]);
- return $scope.$on('$destroy', function() {
- return $interval.cancel(refresh);
- });
-}]).controller('SingleTaskManagerController', ["$scope", "$stateParams", "SingleTaskManagerService", "$interval", "flinkConfig", function($scope, $stateParams, SingleTaskManagerService, $interval, flinkConfig) {
- var refresh;
- $scope.metrics = {};
- SingleTaskManagerService.loadMetrics($stateParams.taskmanagerid).then(function(data) {
- return $scope.metrics = data[0];
- });
- refresh = $interval(function() {
- return SingleTaskManagerService.loadMetrics($stateParams.taskmanagerid).then(function(data) {
- return $scope.metrics = data[0];
- });
- }, flinkConfig["refresh-interval"]);
- return $scope.$on('$destroy', function() {
- return $interval.cancel(refresh);
- });
-}]).controller('SingleTaskManagerLogsController', ["$scope", "$stateParams", "SingleTaskManagerService", "$interval", "flinkConfig", function($scope, $stateParams, SingleTaskManagerService, $interval, flinkConfig) {
- $scope.log = {};
- $scope.taskmanagerid = $stateParams.taskmanagerid;
- SingleTaskManagerService.loadLogs($stateParams.taskmanagerid).then(function(data) {
- return $scope.log = data;
- });
- return $scope.reloadData = function() {
- return SingleTaskManagerService.loadLogs($stateParams.taskmanagerid).then(function(data) {
- return $scope.log = data;
- });
- };
-}]).controller('SingleTaskManagerStdoutController', ["$scope", "$stateParams", "SingleTaskManagerService", "$interval", "flinkConfig", function($scope, $stateParams, SingleTaskManagerService, $interval, flinkConfig) {
- $scope.stdout = {};
- $scope.taskmanagerid = $stateParams.taskmanagerid;
- SingleTaskManagerService.loadStdout($stateParams.taskmanagerid).then(function(data) {
- return $scope.stdout = data;
- });
- return $scope.reloadData = function() {
- return SingleTaskManagerService.loadStdout($stateParams.taskmanagerid).then(function(data) {
- return $scope.stdout = data;
- });
- };
-}]);
-
-angular.module('flinkApp').service('TaskManagersService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
- this.loadManagers = function() {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "taskmanagers").success(function(data, status, headers, config) {
- return deferred.resolve(data['taskmanagers']);
- });
- return deferred.promise;
- };
- return this;
-}]).service('SingleTaskManagerService', ["$http", "flinkConfig", "$q", function($http, flinkConfig, $q) {
- this.loadMetrics = function(taskmanagerid) {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "taskmanagers/" + taskmanagerid + "/metrics").success(function(data, status, headers, config) {
- return deferred.resolve(data['taskmanagers']);
- });
- return deferred.promise;
- };
- this.loadLogs = function(taskmanagerid) {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "taskmanagers/" + taskmanagerid + "/log").success(function(data, status, headers, config) {
- return deferred.resolve(data);
- });
- return deferred.promise;
- };
- this.loadStdout = function(taskmanagerid) {
- var deferred;
- deferred = $q.defer();
- $http.get(flinkConfig.jobServer + "taskmanagers/" + taskmanagerid + "/stdout").success(function(data, status, headers, config) {
- return deferred.resolve(data);
- });
- return deferred.promise;
- };
- return this;
-}]);
-
-//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmNvZmZlZSIsImluZGV4LmpzIiwiY29tbW9uL2RpcmVjdGl2ZXMuY29mZmVlIiwiY29tbW9uL2RpcmVjdGl2ZXMuanMiLCJjb21tb24vZmlsdGVycy5jb2ZmZWUiLCJjb21tb24vZmlsdGVycy5qcyIsImNvbW1vbi9zZXJ2aWNlcy5jb2ZmZWUiLCJjb21tb24vc2VydmljZXMuanMiLCJtb2R1bGVzL2pvYm1hbmFnZXIvam9ibWFuYWdlci5jdHJsLmNvZmZlZSIsIm1vZHVsZXMvam9ibWFuYWdlci9qb2JtYW5hZ2VyLmN0cmwuanMiLCJtb2R1bGVzL2pvYm1hbmFnZXIvam9ibWFuYWdlci5zdmMuY29mZmVlIiwibW9kdWxlcy9qb2JtYW5hZ2VyL2pvYm1hbmFnZXIuc3ZjLmpzIiwibW9kdWxlcy9vdmVydmlldy9vdmVydmlldy5jdHJsLmNvZmZlZSIsIm1vZHVsZXMvb3ZlcnZpZXcvb3ZlcnZpZXcuY3RybC5qcyIsIm1vZHVsZXMvb3ZlcnZpZXcvb3ZlcnZpZXcuc3ZjLmNvZmZlZSIsIm1vZHVsZXMvb3ZlcnZpZXcvb3ZlcnZpZXcuc3ZjLmpzIiwibW9kdWxlcy9qb2JzL2pvYnMuY3RybC5jb2ZmZWUiLCJtb2R1bGVzL2pvYnMvam9icy5jdHJsLmpzIiwibW9kdWxlcy9qb2JzL2pvYnMuZGlyLmNvZmZlZSIsIm1vZHVsZXMvam9icy9qb2JzLmRpci5qcyIsIm1vZHVsZXMvam9icy9qb2JzLnN2Yy5jb2ZmZWUiLCJtb2R1bGVzL2pvYnMvam9icy5zdmMuanMiLCJtb2R1bGVzL2pvYnMvbWV0cm
ljcy5kaXIuY29mZmVlIiwibW9kdWxlcy9qb2JzL21ldHJpY3MuZGlyLmpzIiwibW9kdWxlcy9qb2JzL21ldHJpY3Muc3ZjLmNvZmZlZSIsIm1vZHVsZXMvam9icy9tZXRyaWNzLnN2Yy5qcyIsIm1vZHVsZXMvc3VibWl0L3N1Ym1pdC5jdHJsLmNvZmZlZSIsIm1vZHVsZXMvc3VibWl0L3N1Ym1pdC5jdHJsLmpzIiwibW9kdWxlcy9zdWJtaXQvc3VibWl0LnN2Yy5jb2ZmZWUiLCJtb2R1bGVzL3N1Ym1pdC9zdWJtaXQuc3ZjLmpzIiwibW9kdWxlcy90YXNrbWFuYWdlci90YXNrbWFuYWdlci5jdHJsLmNvZmZlZSIsIm1vZHVsZXMvdGFza21hbmFnZXIvdGFza21hbmFnZXIuY3RybC5qcyIsIm1vZHVsZXMvdGFza21hbmFnZXIvdGFza21hbmFnZXIuc3ZjLmNvZmZlZSIsIm1vZHVsZXMvdGFza21hbmFnZXIvdGFza21hbmFnZXIuc3ZjLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWtCQSxRQUFRLE9BQU8sWUFBWSxDQUFDLGFBQWEsaUJBQWlCLGFBSXpELG1CQUFJLFNBQUMsWUFBRDtFQUNILFdBQVcsaUJBQWlCO0VDckI1QixPRHNCQSxXQUFXLGNBQWMsV0FBQTtJQUN2QixXQUFXLGlCQUFpQixDQUFDLFdBQVc7SUNyQnhDLE9Ec0JBLFdBQVcsZUFBZTs7SUFJN0IsTUFBTSxlQUFlO0VBQ3BCLFdBQVc7RUFFWCxvQkFBb0I7R0FLckIsK0RBQUksU0FBQyxhQUFhLGFBQWEsYUFBYSxXQUF4QztFQzVCSCxPRDZCQSxZQUFZLGFBQWEsS0FBSyxTQUFDLFFBQUQ7SUFDNUIsUUFBUSxPQUFPLGFBQWE7SUFFNUIsWUFBWTtJQzd
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
<TRUNCATED>