incubator-ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From vgog...@apache.org
Subject svn commit: r1344453 - in /incubator/ambari/branches/ambari-186: CHANGES.txt hmc/css/common3.css hmc/js/txnUtils.js
Date Wed, 30 May 2012 20:31:23 GMT
Author: vgogate
Date: Wed May 30 20:31:23 2012
New Revision: 1344453

URL: http://svn.apache.org/viewvc?rev=1344453&view=rev
Log:
Avoid TxnProgressWidget Getting Stuck In An Infinite Loop

Modified:
    incubator/ambari/branches/ambari-186/CHANGES.txt
    incubator/ambari/branches/ambari-186/hmc/css/common3.css
    incubator/ambari/branches/ambari-186/hmc/js/txnUtils.js

Modified: incubator/ambari/branches/ambari-186/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/ambari-186/CHANGES.txt?rev=1344453&r1=1344452&r2=1344453&view=diff
==============================================================================
--- incubator/ambari/branches/ambari-186/CHANGES.txt (original)
+++ incubator/ambari/branches/ambari-186/CHANGES.txt Wed May 30 20:31:23 2012
@@ -6,7 +6,10 @@ characters wide.
 
 Release 0.1.x - unreleased
 
-  AMBARI-308. Externalize message resources; Update styles/messaging on Uninstall Wizard
and Add Nodes Wizard (Yusaku via vgogate)
+  AMBARI-194. Avoid TxnProgressWidget Getting Stuck In An Infinite Loop (rezno via vgogate)
+
+  AMBARI-308. Externalize message resources; Update styles/messaging on Uninstall Wizard
and 
+              Add Nodes Wizard (Yusaku via vgogate)
 
   AMBARI-306. Ignore client components when calculating memory. (hitesh via jitendra)
 

Modified: incubator/ambari/branches/ambari-186/hmc/css/common3.css
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/ambari-186/hmc/css/common3.css?rev=1344453&r1=1344452&r2=1344453&view=diff
==============================================================================
--- incubator/ambari/branches/ambari-186/hmc/css/common3.css (original)
+++ incubator/ambari/branches/ambari-186/hmc/css/common3.css Wed May 30 20:31:23 2012
@@ -133,6 +133,13 @@ span.installationWizardStageNumber {
   color: gray;
 }
 
+.txnNoOpMsg {
+  padding: 4px;
+  font-weight: bolder;
+  font-size: 150%;
+  text-align: center;
+}
+
 .logEntry {
   border:1px solid #B2B299 ;
   background-color:#F0F0E8;

Modified: incubator/ambari/branches/ambari-186/hmc/js/txnUtils.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/ambari-186/hmc/js/txnUtils.js?rev=1344453&r1=1344452&r2=1344453&view=diff
==============================================================================
--- incubator/ambari/branches/ambari-186/hmc/js/txnUtils.js (original)
+++ incubator/ambari/branches/ambari-186/hmc/js/txnUtils.js Wed May 30 20:31:23 2012
@@ -61,183 +61,198 @@ function TxnProgressWidget( txnProgressC
 
   var pdpResponseHandler = {
     success: function (e,pdp) {
+
       /* What we're here to render. */
-      var txnProgressMarkup = '';
+      var txnProgressMarkup = '<ul id=txnProgressStatesListId>';
 
       var txnProgress = e.response.meta.progress;
 
-      /* Make sure we have some progress data to start to show - if not, 
-       * we'll just show a loading image until this is non-null.
-       */
-      if( txnProgress != null ) {
+      var txnProgressStates = txnProgress.subTxns || [];
+      globalYui.log(globalYui.Lang.dump(txnProgressStates));
 
-        var txnProgressStates = txnProgress.subTxns;
-        globalYui.log(globalYui.Lang.dump(txnProgressStates));
+      var progressStateIndex = 0;
 
-        txnProgressMarkup = '<ul id=txnProgressStatesListId>';
+      /* Generate markup for all the "done" states. */
+      for( ; progressStateIndex < txnProgressStates.length; ++progressStateIndex ) {
 
-        var progressStateIndex = 0;
+        var presentTxnProgressState = txnProgressStates[ progressStateIndex ];
 
-        /* Generate markup for all the "done" states. */
-        for( ; progressStateIndex < txnProgressStates.length; ++progressStateIndex ) {
+        /* Step over any progress states that don't deserve to be shown. */
+        if( txnProgressStateShouldBeSkipped( presentTxnProgressState ) ) {
+          continue;
+        }
 
-          var presentTxnProgressState = txnProgressStates[ progressStateIndex ];
+        /* The first sign of a state that isn't done, and we're outta here. */
+        if( presentTxnProgressState.progress != 'COMPLETED' ) {
+          break;
+        }
 
-          /* Step over any progress states that don't deserve to be shown. */
-          if( txnProgressStateShouldBeSkipped( presentTxnProgressState ) ) {
-            continue;
-          }
+        globalYui.log( 'Done loop - ' + progressStateIndex );
 
-          /* The first sign of a state that isn't done, and we're outta here. */
-          if( presentTxnProgressState.progress != 'COMPLETED' ) {
-            break;
-          }
+        txnProgressMarkup += generateSingleTxnProgressStateMarkup
+          ( presentTxnProgressState.description, 'txnProgressStateDone' );
 
-          globalYui.log( 'Done loop - ' + progressStateIndex );
+          globalYui.log("Currently, markup is:" + txnProgressMarkup );
+      }
 
-          txnProgressMarkup += generateSingleTxnProgressStateMarkup
-            ( presentTxnProgressState.description, 'txnProgressStateDone' );
+      /* Next, generate markup for the first "in-progress" state. */
+      for( ; progressStateIndex < txnProgressStates.length; ++progressStateIndex ) {
 
-            globalYui.log("Currently, markup is:" + txnProgressMarkup );
+        var presentTxnProgressState = txnProgressStates[ progressStateIndex ];
+
+        /* Step over any progress states that don't deserve to be shown. */
+        if( txnProgressStateShouldBeSkipped( presentTxnProgressState ) ) {
+          continue;
         }
 
-        /* Next, generate markup for the first "in-progress" state. */
-        for( ; progressStateIndex < txnProgressStates.length; ++progressStateIndex ) {
+        /* We only care to process "in-progress" states.
+         *
+         * However, when a state fails, its progress property is set to
+         * 'FAILED', so check for that as well. Without this, a failed 
+         * state leads to only the previous 'COMPLETED' states being 
+         * rendered (with the 'FAILED' and 'PENDING' states being skipped
+         * over because there's no 'IN_PROGRESS' state) whilst 
+         * #txnProgressStatusDivId shows an overall error (as it rightly 
+         * should) - in short, confusion all around.
+         */
+        if( (presentTxnProgressState.progress == 'IN_PROGRESS') ||
+            (presentTxnProgressState.progress == 'FAILED') ) {
 
-          var presentTxnProgressState = txnProgressStates[ progressStateIndex ];
+          globalYui.log( 'In-progress/failed - ' + progressStateIndex );
 
-          /* Step over any progress states that don't deserve to be shown. */
-          if( txnProgressStateShouldBeSkipped( presentTxnProgressState ) ) {
-            continue;
-          }
+          /* Decide upon what CSS class to assign to the currently-in-progress
+           * state - if an error was marked as having been encountered, assign
+           * the fitting .txnProgressStateError, else just annoint it with
+           * .txnProgressStateInProgress 
+           */
+          var currentProgressStateCssClass = 'txnProgressStateInProgress';
 
-          /* We only care to process "in-progress" states.
-           *
-           * However, when a state fails, its progress property is set to
-           * 'FAILED', so check for that as well. Without this, a failed 
-           * state leads to only the previous 'COMPLETED' states being 
-           * rendered (with the 'FAILED' and 'PENDING' states being skipped
-           * over because there's no 'IN_PROGRESS' state) whilst 
-           * #txnProgressStatusDivId shows an overall error (as it rightly 
-           * should) - in short, confusion all around.
+          /* The 2 possible indications of error are:
+           * 
+           * a) presentTxnProgressState.progress is 'IN_PROGRESS' but 
+           *    txnProgress.encounteredError is true.
+           * b) presentTxnProgressState.progress is 'FAILED'.
            */
-          if( (presentTxnProgressState.progress == 'IN_PROGRESS') ||
+          if( (txnProgress.encounteredError) || 
               (presentTxnProgressState.progress == 'FAILED') ) {
 
-            globalYui.log( 'In-progress/failed - ' + progressStateIndex );
-
-            /* Decide upon what CSS class to assign to the currently-in-progress
-             * state - if an error was marked as having been encountered, assign
-             * the fitting .txnProgressStateError, else just annoint it with
-             * .txnProgressStateInProgress 
-             */
-            var currentProgressStateCssClass = 'txnProgressStateInProgress';
-
-            /* The 2 possible indications of error are:
-             * 
-             * a) presentTxnProgressState.progress is 'IN_PROGRESS' but 
-             *    txnProgress.encounteredError is true.
-             * b) presentTxnProgressState.progress is 'FAILED'.
-             */
-            if( (txnProgress.encounteredError) || 
-                (presentTxnProgressState.progress == 'FAILED') ) {
-
-              currentProgressStateCssClass = 'txnProgressStateError';
-            }
-
-            /* And generate markup for this "in-progress" state. */
-            txnProgressMarkup += generateSingleTxnProgressStateMarkup
-              ( presentTxnProgressState.description, currentProgressStateCssClass );
-
-            /* It's important to manually increment progressStateIndex here, 
-             * to set it up correctly for the upcoming loop.
-             */
-            ++progressStateIndex;
-
-            /* Remember, we only care for the FIRST "in-progress" state.
-             *
-             * Any following "in-progress" states will all be marked as 
-             * "pending", so as to avoid the display from becoming 
-             * disorienting (with multiple states "in-progress").
-             */
-            break;
+            currentProgressStateCssClass = 'txnProgressStateError';
           }
-        }
-
-        /* Finally, generate markup for all the "pending" states. */
-        for( ; progressStateIndex < txnProgressStates.length; ++progressStateIndex ) {
 
-          var presentTxnProgressState = txnProgressStates[ progressStateIndex ];
+          /* And generate markup for this "in-progress" state. */
+          txnProgressMarkup += generateSingleTxnProgressStateMarkup
+            ( presentTxnProgressState.description, currentProgressStateCssClass );
 
-          /* Step over any progress states that don't deserve to be shown. */
-          if( txnProgressStateShouldBeSkipped( presentTxnProgressState ) ) {
-            continue;
-          }
+          /* It's important to manually increment progressStateIndex here, 
+           * to set it up correctly for the upcoming loop.
+           */
+          ++progressStateIndex;
 
-          globalYui.log( 'Pending loop - ' + progressStateIndex );
-          txnProgressMarkup += generateSingleTxnProgressStateMarkup
-            ( presentTxnProgressState.description, 'txnProgressStatePending' );
+          /* Remember, we only care for the FIRST "in-progress" state.
+           *
+           * Any following "in-progress" states will all be marked as 
+           * "pending", so as to avoid the display from becoming 
+           * disorienting (with multiple states "in-progress").
+           */
+          break;
         }
+      }
 
-        var noNeedForFurtherPolling = false;
-        var txnProgressStatusDivContent = '';
-        var txnProgressStatusDivCssClass = '';
+      /* Finally, generate markup for all the "pending" states. */
+      for( ; progressStateIndex < txnProgressStates.length; ++progressStateIndex ) {
 
-        /* We can break this polling cycle in one of 2 ways: 
-         * 
-         * 1) If we are explicitly told by the backend that we're done.
-         */
-        if( txnProgress.processRunning == 0 ) {
+        var presentTxnProgressState = txnProgressStates[ progressStateIndex ];
 
-          noNeedForFurtherPolling = true;
-          /* Be optimistic and assume that no errors were encountered (we'll
-           * get more in touch with reality further below).
-           */
-          txnProgressStatusDivContent = this.txnProgressStatusMessage.success;
-          txnProgressStatusDivCssClass = 'statusOk';
+        /* Step over any progress states that don't deserve to be shown. */
+        if( txnProgressStateShouldBeSkipped( presentTxnProgressState ) ) {
+          continue;
         }
 
-        /* 2) If we encounter an error.
-         *
-         * Note how this is placed after the previous check, so as to serve
-         * as an override in case the backend explicitly told us that we're
-         * done, but an error was encountered in that very last progress report.
+        globalYui.log( 'Pending loop - ' + progressStateIndex );
+        txnProgressMarkup += generateSingleTxnProgressStateMarkup
+          ( presentTxnProgressState.description, 'txnProgressStatePending' );
+      }
+
+      var noNeedForFurtherPolling = false;
+      var txnProgressStatusDivContent = '';
+      var txnProgressStatusDivCssClass = '';
+
+      /* We can break this polling cycle in one of 2 ways: 
+       * 
+       * 1) If we are explicitly told by the backend that we're done.
+       */
+      if( txnProgress.processRunning == 0 ) {
+
+        noNeedForFurtherPolling = true;
+        /* Be optimistic and assume that no errors were encountered (we'll
+         * get more in touch with reality further below).
          */
-        if( txnProgress.encounteredError ) {
+        txnProgressStatusDivContent = this.txnProgressStatusMessage.success;
+        txnProgressStatusDivCssClass = 'statusOk';
+      }
 
-          noNeedForFurtherPolling = true;
-          txnProgressStatusDivContent = this.txnProgressStatusMessage.failure;
-          txnProgressStatusDivCssClass = 'statusError';
-        }
+      /* 2) If we encounter an error.
+       *
+       * Note how this is placed after the previous check, so as to serve
+       * as an override in case the backend explicitly told us that we're
+       * done, but an error was encountered in that very last progress report.
+       */
+      if( txnProgress.encounteredError ) {
 
-        if( noNeedForFurtherPolling ) {
+        noNeedForFurtherPolling = true;
+        txnProgressStatusDivContent = this.txnProgressStatusMessage.failure;
+        txnProgressStatusDivCssClass = 'statusError';
+      }
 
-          /* We've made all the progress we could have, so stop polling. */
-          pdp.stop();
+      if( noNeedForFurtherPolling ) {
 
-          var txnProgressStatusDiv = globalYui.one('#txnProgressStatusDivId');
-          
-          txnProgressStatusDiv.addClass(txnProgressStatusDivCssClass);
-          txnProgressStatusDiv.one('#txnProgressStatusMessageDivId').setContent(txnProgressStatusDivContent);
-          txnProgressStatusDiv.setStyle('display', 'block');
+        /* We've made all the progress we could have, so stop polling. */
+        pdp.stop();
 
-          /* Run the post-completion fixups. */
-          if( txnProgressStatusDivCssClass == 'statusOk' ) {
-            if( this.txnProgressPostCompletionFixup.success ) {
-              this.txnProgressPostCompletionFixup.success(this);
-            }
-          }
-          else if( txnProgressStatusDivCssClass == 'statusError' ) {
-            if( this.txnProgressPostCompletionFixup.failure ) {
-              this.txnProgressPostCompletionFixup.failure(this);
-            }
+        var txnProgressStatusDiv = globalYui.one('#txnProgressStatusDivId');
+        
+        txnProgressStatusDiv.addClass(txnProgressStatusDivCssClass);
+        txnProgressStatusDiv.one('#txnProgressStatusMessageDivId').setContent(txnProgressStatusDivContent);
+        txnProgressStatusDiv.setStyle('display', 'block');
+
+        /* Run the post-completion fixups. */
+        if( txnProgressStatusDivCssClass == 'statusOk' ) {
+          if( this.txnProgressPostCompletionFixup.success ) {
+            this.txnProgressPostCompletionFixup.success(this);
+          }
+        }
+        else if( txnProgressStatusDivCssClass == 'statusError' ) {
+          if( this.txnProgressPostCompletionFixup.failure ) {
+            this.txnProgressPostCompletionFixup.failure(this);
           }
         }
-
-        txnProgressMarkup += '</ul>';
       }
-      else {
-        txnProgressMarkup = '<img id=txnProgressLoadingImgId class=loadingImg src=../images/loading.gif
/>';
+
+      txnProgressMarkup += '</ul>';
+
+      /* Make sure we have some progress data to show - if not, 
+       * we'll just show a loading image until this is non-null.
+       *
+       * The additional check for txnProgress.processRunning is to account 
+       * for cases where there are no subTxns (because it's all a no-op at 
+       * the backend) - the loading image should only be shown as long as 
+       * the backend is still working; after that, we should break out of
+       * the loading image loop and let the user know that there was
+       * nothing to be done.
+       */
+      if( txnProgress.subTxns == null ) {
+        if( txnProgress.processRunning == 0 ) {
+          txnProgressMarkup = 
+            '<br/>' + 
+            '<div class=txnNoOpMsg>' + 
+              'Nothing to do for this transaction; enjoy the freebie!' +
+            '</div>' + 
+            '<br/>';
+        } 
+        else {
+          txnProgressMarkup = 
+            '<img id=txnProgressLoadingImgId class=loadingImg src=../images/loading.gif
/>';
+        }
       }
 
       globalYui.log('About to generate markup: ' + txnProgressMarkup);



Mime
View raw message