Repository: ambari Updated Branches: refs/heads/trunk 27e6797f0 -> 9b331fec7
AMBARI-11413 Ambari Web is sluggish, especially on Hosts page, with 1300 nodes in the cluster. (atkach) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9b331fec Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9b331fec Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9b331fec Branch: refs/heads/trunk Commit: 9b331fec790d376f5b8dd3532979c5c32888dd2c Parents: 27e6797 Author: Andrii Tkach <[email protected]> Authored: Wed May 27 11:44:46 2015 +0300 Committer: Andrii Tkach <[email protected]> Committed: Wed May 27 13:24:06 2015 +0300 ---------------------------------------------------------------------- .../app/controllers/global/update_controller.js | 8 +- .../app/controllers/main/charts/heatmap.js | 25 ++++-- .../app/mappers/component_config_mapper.js | 90 ++++++++++---------- ambari-web/app/mappers/hosts_mapper.js | 24 +++--- ambari-web/app/routes/main.js | 5 +- .../app/templates/main/charts/heatmap.hbs | 56 ++++++------ ambari-web/app/utils/ajax/ajax.js | 2 +- ambari-web/app/views/common/sort_view.js | 11 ++- ambari-web/app/views/main/charts/heatmap.js | 1 - 9 files changed, 122 insertions(+), 100 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/9b331fec/ambari-web/app/controllers/global/update_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/global/update_controller.js b/ambari-web/app/controllers/global/update_controller.js index 8e6252f..af7b69e 100644 --- a/ambari-web/app/controllers/global/update_controller.js +++ b/ambari-web/app/controllers/global/update_controller.js @@ -469,7 +469,10 @@ App.UpdateController = Em.Controller.extend({ }, updateAlertDefinitions: function (callback) { var testUrl = '/data/alerts/alertDefinitions.json'; - var realUrl = '/alert_definitions?fields=*'; + var realUrl = '/alert_definitions?fields=' + + 'AlertDefinition/component_name,AlertDefinition/description,AlertDefinition/enabled,AlertDefinition/id,' + + 'AlertDefinition/ignore_host,AlertDefinition/interval,AlertDefinition/label,AlertDefinition/name,' + + 'AlertDefinition/scope,AlertDefinition/service_name,AlertDefinition/source'; var url = this.getUrl(testUrl, realUrl); App.HttpClient.get(url, App.alertDefinitionsMapper, { @@ -504,7 +507,8 @@ App.UpdateController = Em.Controller.extend({ updateAlertGroups: function (callback) { var testUrl = '/data/alerts/alertGroups.json'; - var realUrl = '/alert_groups?fields=*'; + var realUrl = '/alert_groups?fields=' + + 'AlertGroup/default,AlertGroup/definitions,AlertGroup/id,AlertGroup/name,AlertGroup/targets'; var url = this.getUrl(testUrl, realUrl); App.HttpClient.get(url, App.alertGroupsMapper, { http://git-wip-us.apache.org/repos/asf/ambari/blob/9b331fec/ambari-web/app/controllers/main/charts/heatmap.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/charts/heatmap.js b/ambari-web/app/controllers/main/charts/heatmap.js index f5741f0..9586071 100644 --- a/ambari-web/app/controllers/main/charts/heatmap.js +++ b/ambari-web/app/controllers/main/charts/heatmap.js @@ -24,6 +24,11 @@ App.MainChartsHeatmapController = Em.Controller.extend(App.WidgetSectionMixin, { rackViews: [], /** + * @type {boolean} + */ + isLoaded: false, + + /** * Heatmap metrics that are available choices on the page */ heatmapCategories: [], @@ -65,16 +70,20 @@ App.MainChartsHeatmapController = Em.Controller.extend(App.WidgetSectionMixin, { /** * This function is called from the binded view of the controller */ - loadPageData: function() { + loadPageData: function () { var self = this; - this.resetPageData(); - this.getAllHeatMaps().done(function(allHeatmapData){ - allHeatmapData.items.forEach(function(_allHeatmapData) { - self.get('allHeatmaps').pushObject(_allHeatmapData.WidgetInfo); + this.loadRacks().done(function (data) { + self.set('isLoaded', true); + self.loadRacksSuccessCallback(data); + self.resetPageData(); + self.getAllHeatMaps().done(function (allHeatmapData) { + allHeatmapData.items.forEach(function (_allHeatmapData) { + self.get('allHeatmaps').pushObject(_allHeatmapData.WidgetInfo); + }); + var categories = self.categorizeByServiceName(self.get('allHeatmaps')); + self.set('heatmapCategories', categories); + self.getActiveWidgetLayout(); }); - var categories = self.categorizeByServiceName(self.get('allHeatmaps')); - self.set('heatmapCategories', categories); - self.getActiveWidgetLayout(); }); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/9b331fec/ambari-web/app/mappers/component_config_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/component_config_mapper.js b/ambari-web/app/mappers/component_config_mapper.js index c1f6429..0d2466a 100644 --- a/ambari-web/app/mappers/component_config_mapper.js +++ b/ambari-web/app/mappers/component_config_mapper.js @@ -35,47 +35,51 @@ App.componentConfigMapper = App.QuickDataMapper.create({ map: function (json) { console.time('App.componentConfigMapper execution time'); var hostComponents = []; - var serviceToHostComponentIdMap = {}; + var newHostComponentsMap = {}; var cacheServices = App.cache['services']; - var loadedServiceComponentsMap = this.buildServiceComponentMap(cacheServices); + var currentServiceComponentsMap = this.buildServiceComponentMap(cacheServices); var mapConfig = this.get('config'); // We do not want to parse JSON if there is no need to var hostComponentJsonMap = {}; var hostComponentJsonIds = []; var hostComponentJsonsToRemove = {}; - json.items.forEach(function (item) { - item.host_components.forEach(function (host_component) { - host_component.id = host_component.HostRoles.component_name + '_' + host_component.HostRoles.host_name; - hostComponentJsonIds.push(host_component.id); - hostComponentJsonMap[host_component.id] = host_component; + + if (json.items.length > 0 || this.get('model').find().someProperty('staleConfigs', true)) { + json.items.forEach(function (item) { + item.host_components.forEach(function (host_component) { + host_component.id = host_component.HostRoles.component_name + '_' + host_component.HostRoles.host_name; + hostComponentJsonIds.push(host_component.id); + hostComponentJsonMap[host_component.id] = host_component; + }); }); - }); - this.get('model').find().forEach(function (hostComponent) { - var hostComponentJson = hostComponentJsonMap[hostComponent.get('id')]; - if (!hostComponentJson && - !App.StackServiceComponent.find().findProperty('componentName', hostComponent.get('componentName')).get('isMaster')) { - hostComponent.set('staleConfigs', false); - } - if (hostComponentJson!=null && hostComponent.get('staleConfigs') && + this.get('model').find().forEach(function (hostComponent) { + var hostComponentJson = hostComponentJsonMap[hostComponent.get('id')]; + if (!hostComponentJson && !hostComponent.get('isMaster')) { + hostComponent.set('staleConfigs', false); + } + if (hostComponentJson != null && hostComponent.get('staleConfigs') && hostComponentJson.HostRoles.state == hostComponent.get('workStatus') && hostComponentJson.HostRoles.maintenance_state == hostComponent.get('passiveState')) { - // A component already exists with correct stale_configs flag and other values - no need to load again - hostComponentJsonsToRemove[hostComponentJson.id] = hostComponentJson; - } - }); - hostComponentJsonIds.forEach(function (hcId) { - if(!hostComponentJsonsToRemove[hcId]){ - var host_component = hostComponentJsonMap[hcId]; - var serviceName = host_component.HostRoles.service_name; - hostComponents.push(this.parseIt(host_component, mapConfig)); - if (!serviceToHostComponentIdMap[serviceName]) { - serviceToHostComponentIdMap[serviceName] = []; + // A component already exists with correct stale_configs flag and other values - no need to load again + hostComponentJsonsToRemove[hostComponentJson.id] = hostComponentJson; } - serviceToHostComponentIdMap[serviceName].push(host_component.id); - } - }, this); - App.store.loadMany(this.get('model'), hostComponents); - this.addNewHostComponents(loadedServiceComponentsMap, serviceToHostComponentIdMap, cacheServices); + }); + hostComponentJsonIds.forEach(function (hcId) { + if (!hostComponentJsonsToRemove[hcId]) { + var host_component = hostComponentJsonMap[hcId]; + var serviceName = host_component.HostRoles.service_name; + hostComponents.push(this.parseIt(host_component, mapConfig)); + if (!newHostComponentsMap[serviceName]) { + newHostComponentsMap[serviceName] = []; + } + if (!currentServiceComponentsMap[serviceName][host_component.id]) { + newHostComponentsMap[serviceName].push(host_component.id); + } + } + }, this); + App.store.loadMany(this.get('model'), hostComponents); + this.addNewHostComponents(newHostComponentsMap, cacheServices); + } console.timeEnd('App.componentConfigMapper execution time'); }, @@ -101,25 +105,19 @@ App.componentConfigMapper = App.QuickDataMapper.create({ /** * add only new host-components to every service * to update service - host-component relations in model - * @param loadedServiceComponentsMap - * @param serviceToHostComponentIdMap - * @param cacheServices + * @param {object} newHostComponentsMap + * @param {Array} cacheServices * @return {boolean} */ - addNewHostComponents: function (loadedServiceComponentsMap, serviceToHostComponentIdMap, cacheServices) { - if (!loadedServiceComponentsMap || !serviceToHostComponentIdMap || !cacheServices) return false; - - for (var serviceName in serviceToHostComponentIdMap) { - var loadedService = cacheServices.findProperty('ServiceInfo.service_name', serviceName); - - if (serviceToHostComponentIdMap[serviceName] && loadedService) { - serviceToHostComponentIdMap[serviceName].forEach(function (componentId) { - if (!loadedServiceComponentsMap[serviceName][componentId]) { - loadedService.host_components.push(componentId) - } + addNewHostComponents: function (newHostComponentsMap, cacheServices) { + if (!newHostComponentsMap || !cacheServices) return false; + cacheServices.forEach(function (service) { + if (newHostComponentsMap[service.ServiceInfo.service_name]) { + newHostComponentsMap[service.ServiceInfo.service_name].forEach(function (componentId) { + service.host_components.push(componentId) }); } - } + }, this); return true; } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/9b331fec/ambari-web/app/mappers/hosts_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/hosts_mapper.js b/ambari-web/app/mappers/hosts_mapper.js index 4ce260c..da4bba9 100644 --- a/ambari-web/app/mappers/hosts_mapper.js +++ b/ambari-web/app/mappers/hosts_mapper.js @@ -87,9 +87,11 @@ App.hostsMapper = App.QuickDataMapper.create({ var stackVersions = []; var componentsIdMap = {}; var cacheServices = App.cache['services']; - var loadedServiceComponentsMap = App.get('componentConfigMapper').buildServiceComponentMap(cacheServices); - var serviceToHostComponentIdMap = {}; + var currentServiceComponentsMap = App.get('componentConfigMapper').buildServiceComponentMap(cacheServices); + var newHostComponentsMap = {}; var selectedHosts = App.db.getSelectedHosts('mainHostController'); + var stackUpgradeSupport = App.get('supports.stackUpgrade'); + var clusterName = App.get('clusterName'); json.items.forEach(function (item, index) { item.host_components = item.host_components || []; @@ -103,13 +105,15 @@ App.hostsMapper = App.QuickDataMapper.create({ component.host_name = item.Hosts.host_name; components.push(component); componentsIdMap[component.id] = component; - if (!serviceToHostComponentIdMap[serviceName]) { - serviceToHostComponentIdMap[serviceName] = []; + if (!newHostComponentsMap[serviceName]) { + newHostComponentsMap[serviceName] = []; + } + if (!currentServiceComponentsMap[serviceName][component.id]) { + newHostComponentsMap[serviceName].push(component.id); } - serviceToHostComponentIdMap[serviceName].push(component.id); }, this); - if (App.get('supports.stackUpgrade')) { + if (stackUpgradeSupport) { var currentVersion = item.stack_versions.findProperty('HostStackVersions.state', 'CURRENT'); var currentVersionNumber = currentVersion && currentVersion.repository_versions ? Em.get(currentVersion.repository_versions[0], 'RepositoryVersions.repository_version') : ''; @@ -123,10 +127,10 @@ App.hostsMapper = App.QuickDataMapper.create({ var alertsSummary = item.alerts_summary; item.critical_warning_alerts_count = alertsSummary ? (alertsSummary.CRITICAL || 0) + (alertsSummary.WARNING || 0) : 0; - item.cluster_id = App.get('clusterName'); + item.cluster_id = clusterName; item.index = index; - if (App.get('supports.stackUpgrade')) { + if (stackUpgradeSupport) { this.config = $.extend(this.config, { stack_versions_key: 'stack_versions', stack_versions_type: 'array', @@ -158,7 +162,7 @@ App.hostsMapper = App.QuickDataMapper.create({ if (componentsIdMap[component.get('id')]) componentsIdMap[component.get('id')].display_name_advanced = component.get('displayNameAdvanced'); }); App.store.commit(); - if (App.get('supports.stackUpgrade')) { + if (stackUpgradeSupport) { App.store.loadMany(App.HostStackVersion, stackVersions); } App.store.loadMany(App.HostComponent, components); @@ -168,7 +172,7 @@ App.hostsMapper = App.QuickDataMapper.create({ App.router.set('mainHostController.filteredCount', itemTotal); } //bind host-components with service records - App.get('componentConfigMapper').addNewHostComponents(loadedServiceComponentsMap, serviceToHostComponentIdMap, cacheServices); + App.get('componentConfigMapper').addNewHostComponents(newHostComponentsMap, cacheServices); } console.timeEnd('App.hostsMapper execution time'); } http://git-wip-us.apache.org/repos/asf/ambari/blob/9b331fec/ambari-web/app/routes/main.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js index 5875c77..53482b6 100644 --- a/ambari-web/app/routes/main.js +++ b/ambari-web/app/routes/main.js @@ -142,10 +142,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, { route: '/heatmap', connectOutlets: function (router, context) { router.get('mainController').dataLoading().done(function () { - router.get('mainChartsHeatmapController').loadRacks().done(function(data){ - router.get('mainChartsHeatmapController').loadRacksSuccessCallback(data); - router.get('mainChartsController').connectOutlet('mainChartsHeatmap'); - }); + router.get('mainChartsController').connectOutlet('mainChartsHeatmap'); }); } }), http://git-wip-us.apache.org/repos/asf/ambari/blob/9b331fec/ambari-web/app/templates/main/charts/heatmap.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/charts/heatmap.hbs b/ambari-web/app/templates/main/charts/heatmap.hbs index 05b8da0..a8143fb 100644 --- a/ambari-web/app/templates/main/charts/heatmap.hbs +++ b/ambari-web/app/templates/main/charts/heatmap.hbs @@ -17,37 +17,39 @@ }} <div class="heatmap"> + {{#if isLoaded}} + <div class="container-fluid"> + <div class="row-fluid"> + <div class="span2 legend-column"> - <div class="container-fluid"> - <div class="row-fluid"> - <div class="span2 legend-column"> + {{view view.dropdownView}} - {{view view.dropdownView}} - - {{#if controller.selectedMetric}} - <table class="legend"> - {{#each slot in controller.selectedMetric.slotDefinitions}} - <tr> - <td> - <div class="tile" {{bindAttr style="slot.cssStyle"}}></div> - </td> - <td>{{slot.label}}</td> - </tr> - {{/each}} - </table> - {{t common.maximum}}: - <div id="inputMaximum" class="control-group"> - {{view Ember.TextField type="text" maxlength="8" valueBinding="controller.inputMaximum" class="span6"}} - {{controller.selectedMetric.units}} + {{#if controller.selectedMetric}} + <table class="legend"> + {{#each slot in controller.selectedMetric.slotDefinitions}} + <tr> + <td> + <div class="tile" {{bindAttr style="slot.cssStyle"}}></div> + </td> + <td>{{slot.label}}</td> + </tr> + {{/each}} + </table> + {{t common.maximum}}: + <div id="inputMaximum" class="control-group"> + {{view Ember.TextField type="text" maxlength="8" valueBinding="controller.inputMaximum" class="span6"}} + {{controller.selectedMetric.units}} + </div> + {{/if}} + </div> + {{#if controller.activeWidget}} + <div class="active-widget" {{bindAttr id="activeWidget.id"}}> + {{view activeWidget.viewClass contentBinding="activeWidget" racksBinding = "racks" idBinding="activeWidget.id"}} </div> {{/if}} </div> - {{#if controller.activeWidget}} - <div class="active-widget" {{bindAttr id="activeWidget.id"}}> - {{view activeWidget.viewClass contentBinding="activeWidget" racksBinding = "racks" idBinding="activeWidget.id"}} - </div> - {{/if}} </div> - </div> - + {{else}} + <div class="spinner"></div> + {{/if}} </div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/9b331fec/ambari-web/app/utils/ajax/ajax.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js index bb65e8a..5bc030b 100644 --- a/ambari-web/app/utils/ajax/ajax.js +++ b/ambari-web/app/utils/ajax/ajax.js @@ -464,7 +464,7 @@ var urls = { 'testInProduction': true }, 'background_operations.get_by_request': { - 'real': '/clusters/{clusterName}/requests/{requestId}?fields=*,tasks/Tasks/request_id,tasks/Tasks/command,tasks/Tasks/command_detail,tasks/Tasks/start_time,tasks/Tasks/end_time,tasks/Tasks/exit_code,tasks/Tasks/host_name,tasks/Tasks/id,tasks/Tasks/role,tasks/Tasks/status&minimal_response=true', + 'real': '/clusters/{clusterName}/requests/{requestId}?fields=*,tasks/Tasks/request_id,tasks/Tasks/command,tasks/Tasks/command_detail,tasks/Tasks/host_name,tasks/Tasks/id,tasks/Tasks/role,tasks/Tasks/status&minimal_response=true', 'mock': '/data/background_operations/task_by_request{requestId}.json', 'testInProduction': true }, http://git-wip-us.apache.org/repos/asf/ambari/blob/9b331fec/ambari-web/app/views/common/sort_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/sort_view.js b/ambari-web/app/views/common/sort_view.js index dff40a5..7ed4c72 100644 --- a/ambari-web/app/views/common/sort_view.js +++ b/ambari-web/app/views/common/sort_view.js @@ -239,11 +239,20 @@ var serverWrapperView = Em.View.extend({ */ sort: function (property, order) { var status = order ? 'sorting_desc' : 'sorting_asc'; + var self = this; this.resetSort(); this.get('childViews').findProperty('name', property.get('name')).set('status', status); this.saveSortStatuses(); - this.get('parentView').refresh(); + if (!this.get('parentView.filteringComplete')) { + clearTimeout(this.get('parentView.timeOut')); + this.set('parentView.timeOut', setTimeout(function () { + self.sort(property, order); + }, this.get('parentView.filterWaitingTime'))); + } else { + clearTimeout(this.get('parentView.timeOut')); + this.get('parentView').refresh(); + } }, /** http://git-wip-us.apache.org/repos/asf/ambari/blob/9b331fec/ambari-web/app/views/main/charts/heatmap.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/charts/heatmap.js b/ambari-web/app/views/main/charts/heatmap.js index 431a7e2..e5561d8 100644 --- a/ambari-web/app/views/main/charts/heatmap.js +++ b/ambari-web/app/views/main/charts/heatmap.js @@ -20,7 +20,6 @@ var App = require('app'); App.MainChartsHeatmapView = Em.View.extend({ templateName: require('templates/main/charts/heatmap'), didInsertElement: function () { - this._super(); // set default metric this.get('controller').loadPageData(); $("#heatmapDetailsBlock").hide();
