You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2016/02/17 16:46:10 UTC

ambari git commit: AMBARI-15070. Graph scale behaviour is incorrect if time range is switched before graph data API call is complete (alexantonenko)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.2 e1a735975 -> 4c73a51dc


AMBARI-15070. Graph scale behaviour is incorrect if time range is switched before graph data API call is complete (alexantonenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4c73a51d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4c73a51d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4c73a51d

Branch: refs/heads/branch-2.2
Commit: 4c73a51dc42c243ff100869d323042e75c7f6431
Parents: e1a7359
Author: Alex Antonenko <hi...@gmail.com>
Authored: Wed Feb 17 15:23:19 2016 +0200
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Wed Feb 17 17:46:06 2016 +0200

----------------------------------------------------------------------
 .../app/mixins/common/widgets/widget_mixin.js   | 62 +++++++++++----
 ambari-web/app/utils/ajax/ajax.js               | 12 +++
 .../app/views/common/chart/linear_time.js       | 84 +++++++++++++++-----
 .../main/admin/stack_upgrade/versions_view.js   |  6 +-
 .../test/mixins/common/widget_mixin_test.js     | 18 ++++-
 ambari-web/test/utils/ajax/ajax_test.js         | 32 ++++++++
 .../test/views/common/chart/linear_time_test.js | 10 ++-
 7 files changed, 179 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/4c73a51d/ambari-web/app/mixins/common/widgets/widget_mixin.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/widgets/widget_mixin.js b/ambari-web/app/mixins/common/widgets/widget_mixin.js
index eb2cf19..863b510 100644
--- a/ambari-web/app/mixins/common/widgets/widget_mixin.js
+++ b/ambari-web/app/mixins/common/widgets/widget_mixin.js
@@ -122,9 +122,18 @@ App.WidgetMixin = Ember.Mixin.create({
           startCallName: 'getHostComponentMetrics',
           successCallback: this.getHostComponentMetricsSuccessCallback,
           errorCallback: this.getMetricsErrorCallback,
-          completeCallback: function () {
+          completeCallback: function (xhr) {
             requestCounter--;
             if (requestCounter === 0) this.onMetricsLoaded();
+            if (this.get('graphView')) {
+              var graph = this.get('childViews') && this.get('childViews').findProperty('runningRequests');
+              if (graph) {
+                var requestsArrayName = graph.get('isPopup') ? 'runningPopupRequests' : 'runningRequests';
+                graph.set(requestsArrayName, graph.get(requestsArrayName).reject(function (item) {
+                  return item === xhr;
+                }));
+              }
+            }
           }
         });
       } else {
@@ -134,9 +143,18 @@ App.WidgetMixin = Ember.Mixin.create({
           startCallName: 'getServiceComponentMetrics',
           successCallback: this.getMetricsSuccessCallback,
           errorCallback: this.getMetricsErrorCallback,
-          completeCallback: function () {
+          completeCallback: function (xhr) {
             requestCounter--;
             if (requestCounter === 0) this.onMetricsLoaded();
+            if (this.get('graphView')) {
+              var graph = this.get('childViews') && this.get('childViews').findProperty('runningRequests');
+              if (graph) {
+                var requestsArrayName = graph.get('isPopup') ? 'runningPopupRequests' : 'runningRequests';
+                graph.set(requestsArrayName, graph.get(requestsArrayName).reject(function (item) {
+                  return item === xhr;
+                }));
+              }
+            }
           }
         });
       }
@@ -194,7 +212,7 @@ App.WidgetMixin = Ember.Mixin.create({
    * @returns {$.ajax}
    */
   getServiceComponentMetrics: function (request) {
-    return App.ajax.send({
+    var xhr = App.ajax.send({
       name: 'widgets.serviceComponent.metrics.get',
       sender: this,
       data: {
@@ -203,6 +221,14 @@ App.WidgetMixin = Ember.Mixin.create({
         metricPaths: this.prepareMetricPaths(request.metric_paths)
       }
     });
+    if (this.get('graphView')) {
+      var graph = this.get('childViews') && this.get('childViews').findProperty('runningRequests');
+      if (graph) {
+        var requestsArrayName = graph.get('isPopup') ? 'runningPopupRequests' : 'runningRequests';
+        graph.get(requestsArrayName).push(xhr);
+      }
+    }
+    return xhr;
   },
 
   /**
@@ -232,15 +258,21 @@ App.WidgetMixin = Ember.Mixin.create({
     var metricPaths = this.prepareMetricPaths(request.metric_paths);
 
     if (metricPaths.length) {
-      return App.ajax.send({
-        name: 'widgets.hostComponent.metrics.get',
-        sender: this,
-        data: {
-          componentName: request.component_name,
-          metricPaths: this.prepareMetricPaths(request.metric_paths),
-          hostComponentCriteria: this.computeHostComponentCriteria(request)
-        }
-      });
+      var xhr = App.ajax.send({
+          name: 'widgets.hostComponent.metrics.get',
+          sender: this,
+          data: {
+            componentName: request.component_name,
+            metricPaths: this.prepareMetricPaths(request.metric_paths),
+            hostComponentCriteria: this.computeHostComponentCriteria(request)
+          }
+        }),
+        graph = this.get('graphView') && this.get('childViews') && this.get('childViews').findProperty('runningRequests');
+      if (graph) {
+        var requestsArrayName = graph.get('isPopup') ? 'runningPopupRequests' : 'runningRequests';
+        graph.get(requestsArrayName).push(xhr);
+      }
+      return xhr;
     }
     return jQuery.Deferred().reject().promise();
   },
@@ -302,7 +334,7 @@ App.WidgetMixin = Ember.Mixin.create({
    * @param {string} errorThrown
    */
   getMetricsErrorCallback: function (xhr, textStatus, errorThrown) {
-    if (this.get('graphView')) {
+    if (this.get('graphView') && !xhr.isForcedAbort) {
       var graph = this.get('childViews') && this.get('childViews').findProperty('_showMessage');
       if (graph) {
         if (xhr.readyState == 4 && xhr.status) {
@@ -782,9 +814,9 @@ App.WidgetLoadAggregator = Em.Object.create({
                 subRequest.errorCallback.call(subRequest.context, xhr, textStatus, errorThrown);
               }
             }, this);
-          }).always(function () {
+          }).always(function (xhr) {
               _request.subRequests.forEach(function (subRequest) {
-                subRequest.completeCallback.call(subRequest.context);
+                subRequest.completeCallback.call(subRequest.context, xhr);
               }, this);
             });
       })(bulks[id]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c73a51d/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 4456268..ac6c5ca 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -2977,6 +2977,18 @@ var ajax = Em.Object.extend({
    */
   defaultErrorKDCHandler: function(opt, msg) {
     return App.showInvalidKDCPopup(opt, msg);
+  },
+
+  /**
+   * Abort all requests stored in the certain array
+   * @param requestsArray
+   */
+  abortRequests: function (requestsArray) {
+    requestsArray.forEach(function (xhr) {
+      xhr.isForcedAbort = true;
+      xhr.abort();
+    });
+    requestsArray.clear();
   }
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c73a51d/ambari-web/app/views/common/chart/linear_time.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/chart/linear_time.js b/ambari-web/app/views/common/chart/linear_time.js
index c4a7b81..18b74be 100644
--- a/ambari-web/app/views/common/chart/linear_time.js
+++ b/ambari-web/app/views/common/chart/linear_time.js
@@ -167,6 +167,20 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
    */
   seriesTemplate: null,
 
+  /**
+   * Incomplete metrics requests
+   * @type {array}
+   * @default []
+   */
+  runningRequests: [],
+
+  /**
+   * Incomplete metrics requests for detailed view
+   * @type {array}
+   * @default []
+   */
+  runningPopupRequests: [],
+
   _containerSelector: function () {
     return '#' + this.get('id') + '-container';
   }.property('id'),
@@ -299,6 +313,7 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
     this.$("[rel='ZoomInTooltip']").tooltip('destroy');
     $(this.get('_containerSelector') + ' li.line').off();
     $(this.get('_popupSelector') + ' li.line').off();
+    App.ajax.abortRequests(this.get('runningRequests'));
   },
 
   registerGraph: function () {
@@ -311,16 +326,26 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
   },
 
   loadData: function () {
-    if (this.get('loadGroup') && !this.get('isPopup')) {
+    var self = this,
+      isPopup = this.get('isPopup');
+    if (this.get('loadGroup') && !isPopup) {
       return App.ChartLinearTimeView.LoadAggregator.add(this, this.get('loadGroup'));
     } else {
-      return App.ajax.send({
-        name: this.get('ajaxIndex'),
-        sender: this,
-        data: this.getDataForAjaxRequest(),
-        success: 'loadDataSuccessCallback',
-        error: 'loadDataErrorCallback'
-      });
+      var requestsArrayName = isPopup ? 'runningPopupRequests' : 'runningRequests',
+        request = App.ajax.send({
+          name: this.get('ajaxIndex'),
+          sender: this,
+          data: this.getDataForAjaxRequest(),
+          success: 'loadDataSuccessCallback',
+          error: 'loadDataErrorCallback',
+          callback: function () {
+            self.set(requestsArrayName, self.get(requestsArrayName).reject(function (item) {
+              return item === request;
+            }));
+          }
+        });
+      this.get(requestsArrayName).push(request);
+      return request;
     }
   },
 
@@ -360,15 +385,17 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
   },
 
   loadDataErrorCallback: function (xhr, textStatus, errorThrown) {
-    this.set('isReady', true);
-    if (xhr.readyState == 4 && xhr.status) {
-      textStatus = xhr.status + " " + textStatus;
+    if (!xhr.isForcedAbort) {
+      this.set('isReady', true);
+      if (xhr.readyState == 4 && xhr.status) {
+        textStatus = xhr.status + " " + textStatus;
+      }
+      this._showMessage('warn', this.t('graphs.error.title'), this.t('graphs.error.message').format(textStatus, errorThrown));
+      this.setProperties({
+        hasData: false,
+        isExportButtonHidden: true
+      });
     }
-    this._showMessage('warn', this.t('graphs.error.title'), this.t('graphs.error.message').format(textStatus, errorThrown));
-    this.setProperties({
-      hasData: false,
-      isExportButtonHidden: true
-    });
   },
 
   /**
@@ -1004,6 +1031,7 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
           customDurationFormatted: targetView.get('customDurationFormatted'),
           isPopup: false
         });
+        App.ajax.abortRequests(this.get('graph.runningPopupRequests'));
         this._super();
       },
 
@@ -1039,6 +1067,7 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
         this.set('childViews.firstObject.currentTimeRangeIndex', index);
         this.set('currentTimeIndex', index);
         self.set('currentTimeIndex', index);
+        App.ajax.abortRequests(this.get('graph.runningPopupRequests'));
       },
       currentTimeIndex: self.get('currentTimeIndex'),
 
@@ -1087,6 +1116,9 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, {
       customEndTime: customEndTime,
       customDurationFormatted: customDurationFormatted
     });
+    if (index !== 8 || targetView.get('customStartTime') && targetView.get('customEndTime')) {
+      App.ajax.abortRequests(this.get('runningRequests'));
+    }
   }.observes('parentView.parentView.currentTimeRangeIndex', 'parentView.currentTimeRangeIndex', 'parentView.parentView.customStartTime', 'parentView.customStartTime', 'parentView.parentView.customEndTime', 'parentView.customEndTime'),
   timeUnitSeconds: 3600,
   timeUnitSecondsSetter: function () {
@@ -1413,25 +1445,33 @@ App.ChartLinearTimeView.LoadAggregator = Em.Object.create({
       (function (_request) {
         var fields = self.formatRequestData(_request);
         var hostName = (_request.context.get('content')) ? _request.context.get('content.hostName') : "";
-
-        App.ajax.send({
+        var xhr = App.ajax.send({
           name: _request.name,
           sender: _request.context,
           data: {
             fields: fields,
             hostName: hostName
           }
-        }).done(function (response) {
+        });
+
+        xhr.done(function (response) {
           console.time('==== runRequestsDone');
           _request.subRequests.forEach(function (subRequest) {
             subRequest.context._refreshGraph.call(subRequest.context, response);
           }, this);
           console.timeEnd('==== runRequestsDone');
         }).fail(function (jqXHR, textStatus, errorThrown) {
-          _request.subRequests.forEach(function (subRequest) {
-            subRequest.context.loadDataErrorCallback.call(subRequest.context, jqXHR, textStatus, errorThrown);
-          }, this);
+          if (!jqXHR.isForcedAbort) {
+            _request.subRequests.forEach(function (subRequest) {
+              subRequest.context.loadDataErrorCallback.call(subRequest.context, jqXHR, textStatus, errorThrown);
+            }, this);
+          }
+        }).always(function () {
+          _request.context.set('runningRequests', _request.context.get('runningRequests').reject(function (item) {
+            return item === xhr;
+          }));
         });
+        _request.context.get('runningRequests').push(xhr);
       })(bulks[id]);
     }
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c73a51d/ambari-web/app/views/main/admin/stack_upgrade/versions_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_upgrade/versions_view.js b/ambari-web/app/views/main/admin/stack_upgrade/versions_view.js
index 5984aa4..587850a 100644
--- a/ambari-web/app/views/main/admin/stack_upgrade/versions_view.js
+++ b/ambari-web/app/views/main/admin/stack_upgrade/versions_view.js
@@ -202,12 +202,8 @@ App.MainAdminStackVersionsView = Em.View.extend({
    * stop polling upgrade state
    */
   willDestroyElement: function () {
-    var runningCheckRequests = this.get('controller.runningCheckRequests');
     window.clearTimeout(this.get('updateTimer'));
-    runningCheckRequests.forEach(function (request) {
-      request.abort();
-    });
-    runningCheckRequests.clear();
+    App.ajax.abortRequests(this.get('controller.runningCheckRequests'));
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c73a51d/ambari-web/test/mixins/common/widget_mixin_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mixins/common/widget_mixin_test.js b/ambari-web/test/mixins/common/widget_mixin_test.js
index e458840..ba549a0 100644
--- a/ambari-web/test/mixins/common/widget_mixin_test.js
+++ b/ambari-web/test/mixins/common/widget_mixin_test.js
@@ -394,6 +394,7 @@ describe('App.WidgetMixin', function () {
       cases = [
         {
           graphView: null,
+          isForcedAbort: false,
           metricsLength: 1,
           showMessageCallCount: 0,
           isExportButtonHidden: false,
@@ -401,6 +402,7 @@ describe('App.WidgetMixin', function () {
         },
         {
           graphView: {},
+          isForcedAbort: false,
           metricsLength: 1,
           showMessageCallCount: 0,
           isExportButtonHidden: false,
@@ -409,6 +411,7 @@ describe('App.WidgetMixin', function () {
         {
           graphView: {},
           childViews: [],
+          isForcedAbort: false,
           metricsLength: 1,
           showMessageCallCount: 0,
           isExportButtonHidden: false,
@@ -417,6 +420,7 @@ describe('App.WidgetMixin', function () {
         {
           graphView: {},
           childViews: [Em.Object.create({})],
+          isForcedAbort: false,
           metricsLength: 1,
           showMessageCallCount: 0,
           isExportButtonHidden: false,
@@ -425,10 +429,20 @@ describe('App.WidgetMixin', function () {
         {
           graphView: {},
           childViews: [Em.Object.create({}), view],
+          isForcedAbort: false,
           metricsLength: 0,
           showMessageCallCount: 1,
           isExportButtonHidden: true,
           title: 'graph view is available'
+        },
+        {
+          graphView: {},
+          childViews: [Em.Object.create({}), view],
+          isForcedAbort: true,
+          metricsLength: 1,
+          showMessageCallCount: 0,
+          isExportButtonHidden: false,
+          title: 'request is aborted'
         }
       ],
       messageCases = [
@@ -471,7 +485,9 @@ describe('App.WidgetMixin', function () {
             graphView: item.graphView,
             childViews: item.childViews
           });
-          obj.getMetricsErrorCallback({});
+          obj.getMetricsErrorCallback({
+            isForcedAbort: item.isForcedAbort
+          });
         });
 
         it('metrics array', function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c73a51d/ambari-web/test/utils/ajax/ajax_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/ajax/ajax_test.js b/ambari-web/test/utils/ajax/ajax_test.js
index 5eaafc7..7afd486 100644
--- a/ambari-web/test/utils/ajax/ajax_test.js
+++ b/ambari-web/test/utils/ajax/ajax_test.js
@@ -183,4 +183,36 @@ describe('App.ajax', function() {
       });
     });
   });
+
+  describe('#abortRequests', function () {
+
+    var xhr = {
+        abort: Em.K
+      },
+      requests;
+
+    beforeEach(function () {
+      sinon.spy(xhr, 'abort');
+      xhr.isForcedAbort = false;
+      requests = [xhr, xhr];
+      App.ajax.abortRequests(requests);
+    });
+
+    afterEach(function () {
+      xhr.abort.restore();
+    });
+
+    it('should abort all requests', function () {
+      expect(xhr.abort.calledTwice).to.be.true;
+    });
+
+    it('should mark request as aborted', function () {
+      expect(xhr.isForcedAbort).to.be.true;
+    });
+
+    it('should clear requests array', function () {
+      expect(requests).to.have.length(0);
+    });
+
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c73a51d/ambari-web/test/views/common/chart/linear_time_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/common/chart/linear_time_test.js b/ambari-web/test/views/common/chart/linear_time_test.js
index 5e3f52f..d66ada4 100644
--- a/ambari-web/test/views/common/chart/linear_time_test.js
+++ b/ambari-web/test/views/common/chart/linear_time_test.js
@@ -523,7 +523,8 @@ describe('App.ChartLinearTimeView.LoadAggregator', function () {
       sinon.stub(App.ajax, 'send', function(){
         return {
           done: Em.K,
-          fail: Em.K
+          fail: Em.K,
+          always: Em.K
         }
       });
     });
@@ -533,7 +534,12 @@ describe('App.ChartLinearTimeView.LoadAggregator', function () {
       aggregator.formatRequestData.restore();
     });
     it("", function () {
-      var context = Em.Object.create({content: {hostName: 'host1'}});
+      var context = Em.Object.create({
+        content: {
+          hostName: 'host1'
+        },
+        runningRequests: []
+      });
       var requests = {
         'r1': {
           name: 'r1',