ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dbuz...@apache.org
Subject ambari git commit: AMBARI-19939 Service Config pages load very slowly
Date Thu, 09 Feb 2017 17:07:33 GMT
Repository: ambari
Updated Branches:
  refs/heads/branch-2.5 d64fd8f1e -> 714e60115


AMBARI-19939 Service Config pages load very slowly


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

Branch: refs/heads/branch-2.5
Commit: 714e60115db46584920e3cb1eae7c84ae31b9f5d
Parents: d64fd8f
Author: Denys Buzhor <bdenys@hortonworks.com>
Authored: Thu Feb 9 14:16:32 2017 +0200
Committer: Denys Buzhor <bdenys@hortonworks.com>
Committed: Thu Feb 9 19:07:00 2017 +0200

----------------------------------------------------------------------
 .../controllers/main/service/info/configs.js    | 13 ++-
 .../app/mixins/common/configs/configs_loader.js |  2 +-
 .../app/mixins/common/track_request_mixin.js    | 36 +++++++-
 ambari-web/app/routes/main.js                   | 15 +++-
 .../main/host/configs_service_test.js           |  2 +
 .../main/service/info/config_test.js            | 87 +++++++++++++++++++-
 6 files changed, 144 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/714e6011/ambari-web/app/controllers/main/service/info/configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/configs.js b/ambari-web/app/controllers/main/service/info/configs.js
index 59dbe1d..265a216 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -235,6 +235,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.AddSecurityConfi
    */
   clearStep: function () {
     this.abortRequests();
+    App.router.get('mainController').stopPolling();
     App.set('componentToBeAdded', {});
     App.set('componentToBeDeleted', {});
     this.clearLoadInfo();
@@ -289,7 +290,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.AddSecurityConfi
       acc.push(i);
       return Array.prototype.concat.apply(acc, App.StackService.find(i).get('dependentServiceNames').toArray()).without(serviceName).uniq();
     }, []));
-    this.trackRequest(this.loadConfigTheme(serviceName).always(function () {
+    this.trackRequestChain(this.loadConfigTheme(serviceName).always(function () {
       if (self.get('preSelectedConfigVersion')) {
         self.loadPreSelectedConfigVersion();
       } else {
@@ -300,6 +301,16 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.AddSecurityConfi
   },
 
   /**
+   * Turn on polling when all requests are finished
+   */
+  trackRequestsDidChange: function() {
+    var allCompleted = this.get('requestsInProgress').everyProperty('completed', true);
+    if (this.get('requestsInProgress').length && allCompleted) {
+      App.router.get('mainController').startPolling();
+    }
+  }.observes('requestsInProgress.@each.completed'),
+
+  /**
    * Generate "finger-print" for current <code>stepConfigs[0]</code>
    * Used to determine, if user has some unsaved changes (comparing with <code>hash</code>)
    * @returns {string|null}

http://git-wip-us.apache.org/repos/asf/ambari/blob/714e6011/ambari-web/app/mixins/common/configs/configs_loader.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/configs_loader.js b/ambari-web/app/mixins/common/configs/configs_loader.js
index c888a3e..458c38f 100644
--- a/ambari-web/app/mixins/common/configs/configs_loader.js
+++ b/ambari-web/app/mixins/common/configs/configs_loader.js
@@ -103,7 +103,7 @@ App.ConfigsLoader = Em.Mixin.create(App.GroupsMappingMixin, {
     this.set('versionLoaded', false);
     this.set('selectedVersion', this.get('currentDefaultVersion'));
     this.set('preSelectedConfigVersion', null);
-    this.trackRequest(App.ajax.send({
+    this.trackRequestChain(App.ajax.send({
       name: 'service.serviceConfigVersions.get.current',
       sender: this,
       data: {

http://git-wip-us.apache.org/repos/asf/ambari/blob/714e6011/ambari-web/app/mixins/common/track_request_mixin.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/track_request_mixin.js b/ambari-web/app/mixins/common/track_request_mixin.js
index 6fcc991..07eaf6e 100644
--- a/ambari-web/app/mixins/common/track_request_mixin.js
+++ b/ambari-web/app/mixins/common/track_request_mixin.js
@@ -28,7 +28,36 @@ App.TrackRequestMixin = Em.Mixin.create({
    * @method trackRequest
    */
   trackRequest: function (request) {
-    this.get('requestsInProgress').push(request);
+    var requestId = this.get('requestsInProgress').length;
+    var self = this;
+    this.get('requestsInProgress').pushObject({
+      request: request,
+      id: requestId,
+      status: request.state(),
+      completed: ['resolved', 'rejected'].contains(request.state())
+    });
+    request.always(function() {
+      Em.setProperties(self.get('requestsInProgress').findProperty('id', requestId), {
+        completed: true,
+        status: request.state()
+      });
+    });
+  },
+
+  /**
+   * This method used to put promise to requests queue which is waiting for another request
to be put in tracking queue
+   * after tracking request promise will be completed. Basically it used for places where
trackRequest called after
+   * tracked promise gets resolved.
+   *
+   * @param {$.ajax} request
+   */
+  trackRequestChain: function(request) {
+    var dfd = $.Deferred();
+    request.always(function() {
+      dfd.resolve();
+    });
+    this.trackRequest(request);
+    this.trackRequest(dfd);
   },
 
   /**
@@ -37,8 +66,9 @@ App.TrackRequestMixin = Em.Mixin.create({
    */
   abortRequests: function () {
     this.get('requestsInProgress').forEach(function(r) {
-      if (r && r.readyState !== 4) {
-        r.abort();
+      var request = r.request;
+      if (request && request.readyState !== undefined && request.readyState
!== 4) {
+        request.abort();
       }
     });
     this.get('requestsInProgress').clear();

http://git-wip-us.apache.org/repos/asf/ambari/blob/714e6011/ambari-web/app/routes/main.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js
index 7abe22b..5ead230 100644
--- a/ambari-web/app/routes/main.js
+++ b/ambari-web/app/routes/main.js
@@ -229,7 +229,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
             	    controller.connectOutlet('mainHostSummary');
             	  });
             	} else
-            	  controller.connectOutlet('mainHostSummary');  
+		  controller.connectOutlet('mainHostSummary');
               });
             } else if(App.Service.find().mapProperty('serviceName').contains('HIVE')) {
               App.router.get('configurationController').getConfigsByTags(tags).always(function
() {
@@ -717,6 +717,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
             //if service is not existed then route to default service
             if (item.get('isLoaded')) {
               if (router.get('mainServiceItemController.isConfigurable')) {
+                router.get('mainController').stopPolling();
                 router.get('mainServiceItemController').connectOutlet('mainServiceInfoConfigs',
item);
               }
               else {
@@ -729,13 +730,19 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
             }
           });
         },
-        exitRoute: function (router, context, callback) {
+        exitRoute: function (router, nextRoute, callback) {
           var controller = router.get('mainServiceInfoConfigsController');
+          var exitCallback = function() {
+            if (!/\/main\/services\/\w+\/configs$/.test(nextRoute)) {
+              router.get('mainController').startPolling();
+            }
+            callback();
+          };
           // If another user is running some wizard, current user can't save configs
           if (controller.hasUnsavedChanges() && !router.get('wizardWatcherController.isWizardRunning'))
{
-            controller.showSavePopup(callback);
+            controller.showSavePopup(exitCallback);
           } else {
-            callback();
+            exitCallback();
           }
         }
       }),

http://git-wip-us.apache.org/repos/asf/ambari/blob/714e6011/ambari-web/test/controllers/main/host/configs_service_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/host/configs_service_test.js b/ambari-web/test/controllers/main/host/configs_service_test.js
index deb01ae..85f98b3 100644
--- a/ambari-web/test/controllers/main/host/configs_service_test.js
+++ b/ambari-web/test/controllers/main/host/configs_service_test.js
@@ -107,11 +107,13 @@ describe('App.MainHostServiceConfigsController', function () {
       sinon.stub(controller, 'loadConfigTheme', function() {
         return { always: Em.K };
       });
+      sinon.stub(controller, 'trackRequest');
     });
     afterEach(function() {
       controller.loadCurrentVersions.restore();
       controller.loadConfigTheme.restore();
       App.themesMapper.generateAdvancedTabs.restore();
+      controller.trackRequest.restore();
     });
 		it("should set host", function () {
 			controller.set('content', {

http://git-wip-us.apache.org/repos/asf/ambari/blob/714e6011/ambari-web/test/controllers/main/service/info/config_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/info/config_test.js b/ambari-web/test/controllers/main/service/info/config_test.js
index a06ff8a..7a70127 100644
--- a/ambari-web/test/controllers/main/service/info/config_test.js
+++ b/ambari-web/test/controllers/main/service/info/config_test.js
@@ -38,6 +38,8 @@ describe("App.MainServiceInfoConfigsController", function () {
 
   beforeEach(function () {
     sinon.stub(App.themesMapper, 'generateAdvancedTabs').returns(Em.K);
+    sinon.stub(App.router.get('mainController'), 'startPolling');
+    sinon.stub(App.router.get('mainController'), 'stopPolling');
     mainServiceInfoConfigsController = getController();
   });
 
@@ -45,6 +47,8 @@ describe("App.MainServiceInfoConfigsController", function () {
 
   afterEach(function() {
     App.themesMapper.generateAdvancedTabs.restore();
+    App.router.get('mainController').startPolling.restore();
+    App.router.get('mainController').stopPolling.restore();
   });
 
   describe("#getHash", function () {
@@ -256,12 +260,14 @@ describe("App.MainServiceInfoConfigsController", function () {
       sinon.stub(mainServiceInfoConfigsController, "getHash", function () {
         return "hash"
       });
+      sinon.stub(mainServiceInfoConfigsController, 'trackRequest');
     });
 
     afterEach(function () {
       mainServiceInfoConfigsController.get.restore();
       mainServiceInfoConfigsController.restartServicePopup.restore();
       mainServiceInfoConfigsController.getHash.restore();
+      mainServiceInfoConfigsController.trackRequest.restore();
     });
 
     tests.forEach(function (t) {
@@ -819,9 +825,86 @@ describe("App.MainServiceInfoConfigsController", function () {
       mainServiceInfoConfigsController.get('requestsInProgress').clear();
     });
     it("should set requestsInProgress", function () {
+      var dfd = $.Deferred();
       mainServiceInfoConfigsController.get('requestsInProgress').clear();
-      mainServiceInfoConfigsController.trackRequest({'request': {}});
-      expect(mainServiceInfoConfigsController.get('requestsInProgress')[0]).to.eql({'request':
{}});
+      mainServiceInfoConfigsController.trackRequest(dfd);
+      expect(mainServiceInfoConfigsController.get('requestsInProgress')[0]).to.eql(
+        {
+          request: dfd,
+          id: 0,
+          status: 'pending',
+          completed: false
+        }
+      );
+    });
+    it('should update request status when it become resolved', function() {
+      var request = $.Deferred();
+      mainServiceInfoConfigsController.get('requestsInProgress').clear();
+      mainServiceInfoConfigsController.trackRequest(request);
+      expect(mainServiceInfoConfigsController.get('requestsInProgress')[0]).to.eql({
+        request: request,
+        id: 0,
+        status: 'pending',
+        completed: false
+      });
+      request.resolve();
+      expect(mainServiceInfoConfigsController.get('requestsInProgress')[0]).to.eql({
+        request: request,
+        id: 0,
+        status: 'resolved',
+        completed: true
+      });
+    });
+  });
+
+  describe('#trackRequestChain', function() {
+    beforeEach(function() {
+      mainServiceInfoConfigsController.get('requestsInProgress').clear();
+    });
+    it('should set 2 requests in to requestsInProgress list', function() {
+      mainServiceInfoConfigsController.trackRequestChain($.Deferred());
+      expect(mainServiceInfoConfigsController.get('requestsInProgress')).to.have.length(2);
+    });
+    it('should update status for both requests when tracked requests become resolved', function()
{
+      var request = $.Deferred(),
+          requests;
+      mainServiceInfoConfigsController.trackRequestChain(request);
+      requests = mainServiceInfoConfigsController.get('requestsInProgress');
+      assert.deepEqual(requests.mapProperty('status'), ['pending', 'pending'], 'initial statuses');
+      assert.deepEqual(requests.mapProperty('completed'), [false, false], 'initial completed');
+      request.reject();
+      assert.deepEqual(requests.mapProperty('status'), ['rejected', 'resolved'], 'update
status when rejected');
+      assert.deepEqual(requests.mapProperty('completed'), [true, true], 'initial complete
are false');
+    });
+  });
+
+  describe('#abortRequests', function() {
+    beforeEach(function() {
+      mainServiceInfoConfigsController.get('requestsInProgress').clear();
+    });
+    it('should clear requests when abort called', function() {
+      mainServiceInfoConfigsController.trackRequest($.Deferred());
+      mainServiceInfoConfigsController.abortRequests();
+      expect(mainServiceInfoConfigsController.get('requestsInProgress')).to.have.length(0);
+    });
+    it('should abort requests which are not finished', function() {
+      var pendingRequest = {
+        abort: sinon.spy(),
+        readyState: 0,
+        state: sinon.spy(),
+        always: sinon.spy()
+      };
+      var finishedRequest = {
+        abort: sinon.spy(),
+        readyState: 4,
+        state: sinon.spy(),
+        always: sinon.spy()
+      };
+      mainServiceInfoConfigsController.trackRequest(pendingRequest);
+      mainServiceInfoConfigsController.trackRequest(finishedRequest);
+      mainServiceInfoConfigsController.abortRequests();
+      expect(pendingRequest.abort.calledOnce).to.be.true;
+      expect(finishedRequest.abort.calledOnce).to.be.false;
     });
   });
 


Mime
View raw message