shindig-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ddum...@apache.org
Subject svn commit: r1351468 - in /shindig/trunk/features/src/main/javascript/features: container.util/constant.js container/container.js container/service.js
Date Mon, 18 Jun 2012 19:59:30 GMT
Author: ddumont
Date: Mon Jun 18 19:59:29 2012
New Revision: 1351468

URL: http://svn.apache.org/viewvc?rev=1351468&view=rev
Log:
SHINDIG-1805 - Better error handling around container token refreshes.

Modified:
    shindig/trunk/features/src/main/javascript/features/container.util/constant.js
    shindig/trunk/features/src/main/javascript/features/container/container.js
    shindig/trunk/features/src/main/javascript/features/container/service.js

Modified: shindig/trunk/features/src/main/javascript/features/container.util/constant.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container.util/constant.js?rev=1351468&r1=1351467&r2=1351468&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container.util/constant.js (original)
+++ shindig/trunk/features/src/main/javascript/features/container.util/constant.js Mon Jun
18 19:59:29 2012
@@ -332,7 +332,14 @@ osapi.container.ContainerConfig = {
    *       var token, ttl, error = false;
    *       // Do work to set token and ttl values
    *       if (error) {
-   *         result();
+   *         var undef;
+   *         if (error.isFatal()) {
+   *           // Run all callbacks and let them know there was a horrible error.
+   *           // The container token is not valid, and probably won't be any time soon.
+   *           result(undef, 30, 'There was an error!');  // Try again for a miracle in 30
seconds.
+   *         } else {
+   *           result(undef, 15); // Call me again in 15 seconds, please
+   *         }
    *       } else {
    *         result(token, ttl);
    *       }

Modified: shindig/trunk/features/src/main/javascript/features/container/container.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/container.js?rev=1351468&r1=1351467&r2=1351468&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/container.js (original)
+++ shindig/trunk/features/src/main/javascript/features/container/container.js Mon Jun 18
19:59:29 2012
@@ -519,8 +519,11 @@ osapi.container.Container.prototype.getS
  * unless the token is specified in the optional parameter, in which case the token will
be
  * updated with the provided value immediately.
  *
- * @param {function=} callback Function to run when container token is valid.
- * @param {String=} token The containers new security token.
+ * @param {function(error)=} callback Function to run when refresh completes or is cancelled.
+ *          error will be undefined if there is no error.
+ * @param {String=|boolean} tokenOrWait
+ *          token The container's new security token.
+ *          wait If the callback should not trigger a token fetch.
  * @param {number=} ttl The token's ttl in seconds. If token is specified and ttl is 0,
  *   token refresh will be disabled.
  * @see osapi.container.ContainerConfig.GET_CONTAINER_TOKEN (constants.js)
@@ -539,14 +542,20 @@ osapi.container.Container.prototype.sche
       oldInterval = this.tokenRefreshInterval_,
       newInterval = tokenTTL ? this.setRefreshTokenInterval_(tokenTTL * 1000) : oldInterval,
       refresh = function() {
-        self.updateContainerSecurityToken(function() {
-          self.lastRefresh_ = osapi.container.util.getCurrentTimeMs();
-          // Schedule the next refresh.
-          self.tokenRefreshTimer_ = setTimeout(refresh, newInterval);
-
-          // Do this last so that if it ever errors, we maintain the refresh schedule.
-          self.refreshTokens_();
-        });
+        function callback(error) {
+          if (error) {
+            // try again, but don't force a refresh.
+            setTimeout(gadgets.util.makeClosure(self, self.updateContainerSecurityToken,
callback, true), 1);
+          } else {
+            self.lastRefresh_ = osapi.container.util.getCurrentTimeMs();
+            // Schedule the next refresh.
+            self.tokenRefreshTimer_ = setTimeout(refresh, newInterval);
+
+            // Do this last so that if it ever errors, we maintain the refresh schedule.
+            self.refreshTokens_();
+          }
+        }
+        self.updateContainerSecurityToken(callback);
       };
 
   // If enabled, check to see if we no schedule or if the two intervals are different and
update the schedule.

Modified: shindig/trunk/features/src/main/javascript/features/container/service.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/service.js?rev=1351468&r1=1351467&r2=1351468&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/service.js (original)
+++ shindig/trunk/features/src/main/javascript/features/container/service.js Mon Jun 18 19:59:29
2012
@@ -125,28 +125,36 @@ osapi.container.Service.prototype.getGad
     request['ids'] = uncachedUrls;
     request['language'] = this.getLanguage();
     request['country'] = this.getCountry();
-    this.updateContainerSecurityToken(function() {
-      osapi['gadgets']['metadata'](request).execute(function(response) {
-        // If response entirely fails, augment individual errors.
-        if (response['error']) {
-          for (var i = 0; i < request['ids'].length; i++) {
-            var id = request['ids'][i];
-            finalResponse[id] = { 'error' : response['error'] };
-          }
-
-        // Otherwise, cache response. Augment final response with server response.
-        } else {
-          var currentTimeMs = osapi.container.util.getCurrentTimeMs();
-          for (var id in response) {
-            var resp = response[id];
-            self.updateResponse_(resp, id, currentTimeMs);
-            self.cachedMetadatas_[id] = resp;
-            finalResponse[id] = resp;
-          }
+    this.updateContainerSecurityToken(function(error) {
+      if (error) {
+        for (var i = 0; i < request['ids'].length; i++) {
+          var id = request['ids'][i];
+          finalResponse[id] = { 'error' : error };
         }
-
         callback(finalResponse);
-      });
+      } else {
+        osapi['gadgets']['metadata'](request).execute(function(response) {
+          // If response entirely fails, augment individual errors.
+          if (response['error']) {
+            for (var i = 0; i < request['ids'].length; i++) {
+              var id = request['ids'][i];
+              finalResponse[id] = { 'error' : response['error'] };
+            }
+
+          // Otherwise, cache response. Augment final response with server response.
+          } else {
+            var currentTimeMs = osapi.container.util.getCurrentTimeMs();
+            for (var id in response) {
+              var resp = response[id];
+              self.updateResponse_(resp, id, currentTimeMs);
+              self.cachedMetadatas_[id] = resp;
+              finalResponse[id] = resp;
+            }
+          }
+
+          callback(finalResponse);
+        });
+      }
     });
   }
 };
@@ -243,11 +251,15 @@ osapi.container.Service.prototype.getGad
   };
 
   // If we have a custom token fetch function, call it -- otherwise use the default
-  self.updateContainerSecurityToken(function() {
-    if (self.config_[osapi.container.ContainerConfig.GET_GADGET_TOKEN]) {
-      self.config_[osapi.container.ContainerConfig.GET_GADGET_TOKEN](request, tokenResponseCallback);
+  self.updateContainerSecurityToken(function(error) {
+    if (error) {
+      tokenResponseCallback({'error': error});
     } else {
-      osapi['gadgets']['token'](request).execute(tokenResponseCallback);
+      if (self.config_[osapi.container.ContainerConfig.GET_GADGET_TOKEN]) {
+        self.config_[osapi.container.ContainerConfig.GET_GADGET_TOKEN](request, tokenResponseCallback);
+      } else {
+        osapi['gadgets']['token'](request).execute(tokenResponseCallback);
+      }
     }
   });
 };
@@ -410,14 +422,14 @@ osapi.container.Service.prototype.getCou
       callbacks = [];
 
 
-  function runCallbacks(callbacks) {
+  function runCallbacks(callbacks, error) {
     while (callbacks.length) {
-      callbacks.shift().call(null); // Window context
+      callbacks.shift().call(null, error); // Window context
     }
   }
 
   function refresh(fetch_once) {
-    fetching = true;
+    var self = this;
     if (containerTimeout) {
       clearTimeout(containerTimeout);
       containerTimeout = 0;
@@ -425,26 +437,30 @@ osapi.container.Service.prototype.getCou
 
     var fetch = fetch_once || this.config_[osapi.container.ContainerConfig.GET_CONTAINER_TOKEN];
     if (fetch) {
-      var self = this;
-      fetch(function(token, ttl) { // token and ttl may be undefined in the case of an error
-        fetching = false;
-
-        // Use last known ttl if there was an error
-        containerTokenTTL = token ? (ttl * 1000 * 0.8) : containerTokenTTL;
-        if (containerTokenTTL) {
-          // Refresh again in 80% of the reported ttl
-          // Pass null in to closure because FF behaves un-expectedly when that param is
not explicitly provided.
-          containerTimeout = setTimeout(gadgets.util.makeClosure(self, refresh, null), containerTokenTTL);
-        }
+      if (!fetching) {
+        fetching = true;
+        fetch(function(token, ttl, error) { // token and ttl may be undefined in the case
of an error
+          fetching = false;
+
+          // Use last known ttl if there was an error
+          containerTokenTTL = typeof(ttl) == 'number' ? (ttl * 1000 * 0.8) : containerTokenTTL;
+          if (containerTokenTTL) {
+            // Refresh again in 80% of the reported ttl
+            // Pass null in to closure because FF behaves un-expectedly when that param is
not explicitly provided.
+            containerTimeout = setTimeout(gadgets.util.makeClosure(self, refresh, null),
containerTokenTTL);
+          }
 
-        if (token) {
-          // Looks like everything worked out...  let's update the token.
-          shindig.auth.updateSecurityToken(token);
-          lastRefresh =  osapi.container.util.getCurrentTimeMs();
-          // And then run all the callbacks waiting for this.
-          runCallbacks(callbacks);
-        }
-      });
+          if (token) {
+            // Looks like everything worked out...  let's update the token.
+            shindig.auth.updateSecurityToken(token);
+            lastRefresh =  osapi.container.util.getCurrentTimeMs();
+            // And then run all the callbacks waiting for this.
+            runCallbacks(callbacks);
+          } else if (error) {
+            runCallbacks(callbacks, error);
+          }
+        });
+      }
     } else {
       fetching = false;
       // Fail gracefully, container supplied no fetch function. Do not hold on to callbacks.
@@ -455,8 +471,11 @@ osapi.container.Service.prototype.getCou
   /**
    * @see osapi.container.Container.prototype.updateContainerSecurityToken
    */
-  osapi.container.Service.prototype.updateContainerSecurityToken = function(callback, token,
ttl) {
-    var now = osapi.container.util.getCurrentTimeMs(),
+  osapi.container.Service.prototype.updateContainerSecurityToken = function(callback, tokenOrWait,
ttl) {
+    var undef,
+        now = osapi.container.util.getCurrentTimeMs(),
+        token = typeof(tokenOrWait) != 'boolean' && tokenOrWait || undef,
+        wait = typeof(tokenOrWait) == 'boolean' && tokenOrWait,
         needsRefresh = containerTokenTTL &&
             (fetching || token || !lastRefresh || now > lastRefresh + containerTokenTTL);
     if (needsRefresh) {
@@ -478,8 +497,14 @@ osapi.container.Service.prototype.getCou
         refresh.call(this, function(result) {
           result(token, ttl);
         });
-      } else if (!fetching) {
-        // There's no fetch going on right now. We need to start one because the token needs
a refresh
+      } else if (!fetching && !wait) {
+        // There's no fetch going on right now. Unless wait is true, we need to start one
right away
+        // because the token needs a refresh.
+
+        // If wait is true, the callback really just wants a valid token. It may be called
with an
+        // error for informational purposes, but it's likely the callback will simply queue
up
+        // immediately if there was an error.  To avoid spamming the refresh method, we allow
them to
+        // specify `wait` so that it can wait for success without forcing a fetch.
         refresh.call(this);
       }
     } else if (callback) {



Mime
View raw message