Author: yusaku
Date: Wed Feb 27 20:10:01 2013
New Revision: 1450945

URL: http://svn.apache.org/r1450945
Log:
AMBARI-1519. Ambari Web goes back and forth between frozen and usable state 
peridocially on a large cluster. (yusaku)

Modified:
    incubator/ambari/trunk/CHANGES.txt
    incubator/ambari/trunk/ambari-web/app/mappers/status_mapper.js
    incubator/ambari/trunk/ambari-web/app/models/host.js
    incubator/ambari/trunk/ambari-web/app/models/service.js

Modified: incubator/ambari/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1450945&r1=1450944&r2=1450945&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Wed Feb 27 20:10:01 2013
@@ -387,6 +387,9 @@ Trunk (unreleased changes):
 
  BUG FIXES
 
+ AMBARI-1519. Ambari Web goes back and forth between frozen and usable state
+ peridocially on a large cluster. (yusaku)
+
  AMBARI-1499. Add hosts is broken. (yusaku)
 
  AMBARI-1501. Nagios alerts do not update automatically. (yusaku)

Modified: incubator/ambari/trunk/ambari-web/app/mappers/status_mapper.js
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/mappers/status_mapper.js?rev=1450945&r1=1450944&r2=1450945&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/mappers/status_mapper.js (original)
+++ incubator/ambari/trunk/ambari-web/app/mappers/status_mapper.js Wed Feb 27 
20:10:01 2013
@@ -58,6 +58,8 @@ App.statusMapper = App.QuickDataMapper.c
         }, this)
       }, this);
 
+      // console.profile("App.statusMapper.map() profile");
+
       var hostComponents = App.HostComponent.find();
 
       hostComponents.forEach(function(hostComponent) {
@@ -67,6 +69,8 @@ App.statusMapper = App.QuickDataMapper.c
         }
       });
 
+      // console.profileEnd();
+
       console.log('out status mapper.  Took ' + (new Date().getTime() - start) 
+ 'ms');
     }
   }

Modified: incubator/ambari/trunk/ambari-web/app/models/host.js
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/models/host.js?rev=1450945&r1=1450944&r2=1450945&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/models/host.js (original)
+++ incubator/ambari/trunk/ambari-web/app/models/host.js Wed Feb 27 20:10:01 
2013
@@ -122,7 +122,19 @@ App.Host = DS.Model.extend({
     if (this.get('loadFifteen') != null) return 
this.get('loadFifteen').toFixed(2);
   }.property('loadOne', 'loadFive', 'loadFifteen'),
 
-  healthClass: function(){
+  // Instead of making healthStatus a computed property that listens on 
[email protected],
+  // we are creating a separate observer _updateHealthStatus.  This is so that 
healthStatus is updated
+  // only once after the run loop.  This is because Ember invokes the computed 
property every time
+  // a property that it depends on changes.  For example, App.statusMapper's 
map function would invoke
+  // the computed property too many times and freezes the UI without this hack.
+  // See 
http://stackoverflow.com/questions/12467345/ember-js-collapsing-deferring-expensive-observers-or-computed-properties
+  healthClass: '',
+
+  _updateHealthClass: function(){
+    Ember.run.once(this, 'updateHealthClass');
+  }.observes('healthStatus', '[email protected]'),
+
+  updateHealthClass: function(){
     var healthStatus = this.get('healthStatus');
     /**
      * Do nothing until load
@@ -147,8 +159,9 @@ App.Host = DS.Model.extend({
         healthStatus = status;
       }
     }
-    return 'health-status-' + healthStatus;
-  }.property('healthStatus', '[email protected]'),
+    this.set('healthClass', 'health-status-' + healthStatus);
+  },
+
   healthToolTip: function(){
     var hostComponents = this.get('hostComponents').filter(function(item){
       if(item.get('workStatus') !== App.HostComponentStatus.started){

Modified: incubator/ambari/trunk/ambari-web/app/models/service.js
URL: 
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/models/service.js?rev=1450945&r1=1450944&r2=1450945&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/models/service.js (original)
+++ incubator/ambari/trunk/ambari-web/app/models/service.js Wed Feb 27 20:10:01 
2013
@@ -35,24 +35,45 @@ App.Service = DS.Model.extend({
     return !(this.get('healthStatus') == 'green');
   }.property('healthStatus'),
 
-  healthStatus: function () {
+  // Instead of making healthStatus a computed property that listens on 
[email protected],
+  // we are creating a separate observer _updateHealthStatus.  This is so that 
healthStatus is updated
+  // only once after the run loop.  This is because Ember invokes the computed 
property every time
+  // a property that it depends on changes.  For example, App.statusMapper's 
map function would invoke
+  // the computed property too many times and freezes the UI without this hack.
+  // See 
http://stackoverflow.com/questions/12467345/ember-js-collapsing-deferring-expensive-observers-or-computed-properties
+  healthStatus: '',
+
+  updateHealthStatus: function () {
+    // console.log('model:service.healthStatus ' + this.get('serviceName'));
     var components = this.get('hostComponents').filterProperty('isMaster', 
true);
     var isGreen = (this.get('serviceName') === 'HBASE' ?
       components.someProperty('workStatus', App.HostComponentStatus.started) :
       components.everyProperty('workStatus', App.HostComponentStatus.started)) 
;
 
     if (isGreen) {
-      return 'green';
+      this.set('healthStatus', 'green');
     } else if (components.someProperty('workStatus', 
App.HostComponentStatus.starting)) {
-      return 'green-blinking';
+      this.set('healthStatus', 'green-blinking');
     } else if (components.someProperty('workStatus', 
App.HostComponentStatus.stopped)) {
-      return 'red';
+      this.set('healthStatus', 'red');
     } else {
-      return 'red-blinking';
+      this.set('healthStatus', 'red-blinking');
     }
-  }.property('[email protected]'),
+  },
+
+  /**
+   * Every time when changes workStatus of any component we schedule 
recalculating values related from them
+   */
+  _updateHealthStatus: (function() {
+    Ember.run.once(this, 'updateHealthStatus');
+    Ember.run.once(this, 'updateIsStopped');
+    Ember.run.once(this, 'updateIsStarted');
+  }).observes('[email protected]'),
 
-  isStopped: function () {
+  isStopped: false,
+  isStarted: false,
+
+  updateIsStopped: function () {
     var components = this.get('hostComponents');
     var flag = true;
     components.forEach(function (_component) {
@@ -60,13 +81,16 @@ App.Service = DS.Model.extend({
         flag = false;
       }
     }, this);
-    return flag;
-  }.property('[email protected]'),
+    this.set('isStopped', flag);
+  },
 
-  isStarted: function () {
+  updateIsStarted: function () {
     var components = this.get('hostComponents').filterProperty('isMaster', 
true);
-    return components.everyProperty('workStatus', 
App.HostComponentStatus.started);
-  }.property('[email protected]'),
+    this.set('isStarted',
+      components.everyProperty('workStatus', App.HostComponentStatus.started)
+    );
+  },
+
   isMaintained: function () {
     var maintainedServices = [
       "HDFS",
@@ -79,10 +103,9 @@ App.Service = DS.Model.extend({
       "PIG",
       "SQOOP"
     ];
-    for (var i in maintainedServices) {
-      if (this.get('serviceName') == maintainedServices[i]) return true;
-    }
+    return maintainedServices.contains(this.get('serviceName'));
   }.property('serviceName'),
+
   isConfigurable: function () {
     var configurableServices = [
       "HDFS",
@@ -96,10 +119,9 @@ App.Service = DS.Model.extend({
       "SQOOP",
       "NAGIOS"
     ];
-    for (var i in configurableServices) {
-      if (this.get('serviceName') == configurableServices[i]) return true;
-    }
+    return configurableServices.contains(this.get('serviceName'));
   }.property('serviceName'),
+
   displayName: function () {
     switch (this.get('serviceName').toLowerCase()) {
       case 'hdfs':
@@ -133,7 +155,7 @@ App.Service = DS.Model.extend({
 
 App.Service.Health = {
   live: "LIVE",
-  dead: "DEAD",
+  dead: "DEAD-RED",
   starting: "STARTING",
   stopping: "STOPPING",
 


Reply via email to