Repository: ambari Updated Branches: refs/heads/trunk 7d6731b7f -> 1d7fa6ad0
AMBARI-7483 Slider View: Stopping ResourceManager results in multiple calls waiting to finish. (atkach) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/1d7fa6ad Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1d7fa6ad Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1d7fa6ad Branch: refs/heads/trunk Commit: 1d7fa6ad02f59c5f1854fb58f184cbab8e82383a Parents: 7d6731b Author: atkach <[email protected]> Authored: Thu Sep 25 13:01:02 2014 +0300 Committer: atkach <[email protected]> Committed: Thu Sep 25 13:01:02 2014 +0300 ---------------------------------------------------------------------- .../app/controllers/slider_apps_controller.js | 15 +++++++- .../src/main/resources/ui/app/helpers/ajax.js | 7 +++- .../src/main/resources/ui/app/initialize.js | 2 +- .../ui/app/mappers/slider_apps_mapper.js | 39 +++++++++++++++++++- .../resources/ui/app/mixins/run_periodically.js | 37 +++++++++++++++++-- .../ui/app/templates/unavailable_apps.hbs | 19 ++++++++++ .../src/main/resources/ui/app/translations.js | 3 +- 7 files changed, 113 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/1d7fa6ad/contrib/views/slider/src/main/resources/ui/app/controllers/slider_apps_controller.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_apps_controller.js b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_apps_controller.js index 1bca7e4..bd3b284 100644 --- a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_apps_controller.js +++ b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_apps_controller.js @@ -17,5 +17,18 @@ */ App.SliderAppsController = Ember.ArrayController.extend({ - + /** + * show modal popup that says apps currently unavailable + */ + showUnavailableAppsPopup: function() { + Bootstrap.ModalManager.open( + "apps-warning-modal", + Em.I18n.t('common.warning'), + 'unavailable_apps', + [ + Ember.Object.create({title: Em.I18n.t('ok'), dismiss: 'modal'}) + ], + this + ); + } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/1d7fa6ad/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js b/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js index 5ecd9c8..8447d3c 100644 --- a/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js +++ b/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js @@ -85,6 +85,11 @@ var urls = { Accept: "text/plain; charset=utf-8", "Content-Type": "text/plain; charset=utf-8" }, + 'format': function() { + return { + timeout: 20000 + }; + }, schema: { required: ['items'], properties: { @@ -329,7 +334,7 @@ var ajax = Em.Object.extend({ opt.error = function (request, ajaxOptions, error) { if (config.error) { config.sender[config.error](request, ajaxOptions, error, opt, params); - } else { + } else if (config.sender.defaultErrorHandler) { config.sender.defaultErrorHandler.call(config.sender, request, opt.url, opt.type, opt.showErrorPopup); } }; http://git-wip-us.apache.org/repos/asf/ambari/blob/1d7fa6ad/contrib/views/slider/src/main/resources/ui/app/initialize.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/initialize.js b/contrib/views/slider/src/main/resources/ui/app/initialize.js index 2a85588..4e14d14 100755 --- a/contrib/views/slider/src/main/resources/ui/app/initialize.js +++ b/contrib/views/slider/src/main/resources/ui/app/initialize.js @@ -113,7 +113,7 @@ App.initializer({ }); application.SliderController.proto().initResources(); application.ApplicationTypeMapper.load(); - application.SliderAppsMapper.loop('load'); + application.SliderAppsMapper.run('load'); } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/1d7fa6ad/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js b/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js index 70583f4..d224928 100644 --- a/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js +++ b/contrib/views/slider/src/main/resources/ui/app/mappers/slider_apps_mapper.js @@ -31,16 +31,46 @@ App.SliderAppsMapper = App.Mapper.createWithMixins(App.RunPeriodically, { }, /** + * @type {bool} + */ + isWarningPopupShown: false, + + /** + * @type {bool} + */ + isChained: true, + /** * Load data from <code>App.urlPrefix + this.urlSuffix</code> one time * @method load * @return {$.ajax} */ load: function () { - return App.ajax.send({ + var self = this; + var dfd = $.Deferred(); + + App.ajax.send({ name: 'mapper.applicationApps', sender: this, success: 'parse' - }); + }).fail(function(jqXHR, textStatus){ + if (textStatus === "timeout" && !self.get('isWarningPopupShown')) { + self.set('isWarningPopupShown', true); + window.App.__container__.lookup('controller:SliderApps').showUnavailableAppsPopup(); + } + }).complete(function(){ + dfd.resolve(); + }) + return dfd.promise(); + }, + + /** + * close warning popup if apps became available + * @return {*} + */ + closeWarningPopup: function() { + if (Bootstrap.ModalManager.get('apps-warning-modal')) { + Bootstrap.ModalManager.close('apps-warning-modal'); + } }, /** @@ -199,6 +229,11 @@ App.SliderAppsMapper = App.Mapper.createWithMixins(App.RunPeriodically, { self = this, appsToDelete = App.SliderApp.store.all('sliderApp').get('content').mapProperty('id'); + if (this.get('isWarningPopupShown')) { + this.closeWarningPopup(); + this.set('isWarningPopupShown', false); + } + data.items.forEach(function (app) { var componentsId = app.components ? self.parseComponents(app) : [], configs = app.configs ? self.parseConfigs(app) : {}, http://git-wip-us.apache.org/repos/asf/ambari/blob/1d7fa6ad/contrib/views/slider/src/main/resources/ui/app/mixins/run_periodically.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/mixins/run_periodically.js b/contrib/views/slider/src/main/resources/ui/app/mixins/run_periodically.js index 25d5aaf..68bfc3f 100644 --- a/contrib/views/slider/src/main/resources/ui/app/mixins/run_periodically.js +++ b/contrib/views/slider/src/main/resources/ui/app/mixins/run_periodically.js @@ -44,12 +44,18 @@ App.RunPeriodically = Ember.Mixin.create({ timer: null, /** + * flag to indicate whether each call should be chained to previous one + * @type {bool} + */ + isChained: false, + + /** * Run <code>methodName</code> periodically with <code>interval</code> * @param {string} methodName method name to run periodically * @param {bool} initRun should methodName be run before setInterval call (default - true) * @method run */ - loop: function(methodName, initRun) { + run: function(methodName, initRun) { initRun = Em.isNone(initRun) ? true : initRun; var self = this, interval = this.get('interval'); @@ -57,9 +63,34 @@ App.RunPeriodically = Ember.Mixin.create({ if (initRun) { this[methodName](); } + + if (this.get('isChained')) { + this.loop(self, methodName, interval); + } else { + this.set('timer', + setInterval(function () { + self[methodName](); + }, interval) + ); + } + }, + + /** + * Start chain of calls of <code>methodName</code> with <code>interval</code> + * next call made only after previous is finished + * callback should return deffered object to run next loop + * @param {object} context + * @param {string} methodName method name to run periodically + * @param {number} interval + * @method loop + */ + loop: function (context, methodName, interval) { + var self = this; this.set('timer', - setInterval(function () { - self[methodName](); + setTimeout(function () { + context[methodName]().done(function () { + self.loop(context, methodName, interval); + }); }, interval) ); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/1d7fa6ad/contrib/views/slider/src/main/resources/ui/app/templates/unavailable_apps.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/templates/unavailable_apps.hbs b/contrib/views/slider/src/main/resources/ui/app/templates/unavailable_apps.hbs new file mode 100644 index 0000000..f791d15 --- /dev/null +++ b/contrib/views/slider/src/main/resources/ui/app/templates/unavailable_apps.hbs @@ -0,0 +1,19 @@ +{{! +* 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. +}} + +{{t slider.apps.unavailable}} http://git-wip-us.apache.org/repos/asf/ambari/blob/1d7fa6ad/contrib/views/slider/src/main/resources/ui/app/translations.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/translations.js b/contrib/views/slider/src/main/resources/ui/app/translations.js index c43f4f1..014231a 100644 --- a/contrib/views/slider/src/main/resources/ui/app/translations.js +++ b/contrib/views/slider/src/main/resources/ui/app/translations.js @@ -48,7 +48,7 @@ Em.I18n.translations = { 'finished': 'Finished', 'diagnostics': 'Diagnostics', 'description': 'Description', - 'status': 'Status', + 'warning': 'Warning', 'key': 'Key', 'remove': 'Remove', 'send': 'Send', @@ -78,6 +78,7 @@ Em.I18n.translations = { 'slider.apps.title': 'Slider Apps', 'slider.apps.create': 'Create App', + 'slider.apps.unavailable': 'HDFS or YARN services are currently unaccessible', 'sliderApps.filters.info': '{0} of {1} sliders showing', 'sliderApp.flex.invalid_counts': 'Instance counts should be integer and >= 0',
