[Pkg-mozext-commits] [gcontactsync] 40/88: Issue #22 - Throttle requests to mitigate 503 errors

David Prévot taffit at moszumanska.debian.org
Thu Sep 18 20:52:28 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository gcontactsync.

commit 79d609effac905b337960033917c8f6045e8c683
Author: Josh Geenen <joshgeenen at gmail.com>
Date:   Wed Feb 26 21:16:36 2014 -0600

    Issue #22 - Throttle requests to mitigate 503 errors
---
 build.sh                                 |   2 +-
 src/content/Preferences.js               |   4 +-
 src/content/Sync.js                      |   6 +-
 src/content/ThrottleTest.js              | 175 +++++++++++++++++++++++++++++++
 src/content/options.xul                  |  22 ++++
 src/content/synonyms.js                  |  47 ++++++++-
 src/defaults/preferences/gContactSync.js |   4 +-
 src/install.rdf                          |   2 +-
 src/locale/en-US/gcontactsync.properties |   8 ++
 src/locale/en-US/options.dtd             |   4 +
 10 files changed, 264 insertions(+), 10 deletions(-)

diff --git a/build.sh b/build.sh
index 878e2b5..0a3ca68 100755
--- a/build.sh
+++ b/build.sh
@@ -10,7 +10,7 @@
 # Edit install.rdf and content/synonyms.js to change the actual VERSION
 #VERSION=0.3.6
 #SRC_DIR=./src3
-VERSION=0.4.0rc2
+VERSION=0.4.0rc3pre
 SRC_DIR=./src
 
 # Dest should be absolute or relative to SRC_DIR
diff --git a/src/content/Preferences.js b/src/content/Preferences.js
index 0ace4d9..51f2288 100644
--- a/src/content/Preferences.js
+++ b/src/content/Preferences.js
@@ -206,10 +206,10 @@ com.gContactSync.Preferences = {
     overrideGetCardForEmail:  new com.gContactSync.Pref("overrideGetCardForEmail",  "bool", true),
     syncPhoneticNames:        new com.gContactSync.Pref("syncPhoneticNames",        "bool", true),
     newContactPhotoDelay:     new com.gContactSync.Pref("newContactPhotoDelay",      "int", 0),
-    remoteActionDelay:        new com.gContactSync.Pref("remoteActionDelay",         "int", 0),
     v04UpgradeNeeded:         new com.gContactSync.Pref("v04UpgradeNeeded",         "bool", false),
     v04RCUpgradeNeeded:       new com.gContactSync.Pref("v04RCUpgradeNeeded",       "bool", false),
-    httpRequestTimeout:       new com.gContactSync.Pref("httpRequestTimeout",        "int", 0)
+    httpRequestTimeout:       new com.gContactSync.Pref("httpRequestTimeout",        "int", 0),
+    httpRequestDelay:         new com.gContactSync.Pref("httpRequestDelay",          "int", 120)
   },
   /**
    * Gets a preference given its branch, name, and type
diff --git a/src/content/Sync.js b/src/content/Sync.js
index 969f09b..ffd07ac 100644
--- a/src/content/Sync.js
+++ b/src/content/Sync.js
@@ -696,15 +696,15 @@ com.gContactSync.Sync = {
   },
   /**
    * Calls the given function after the timeout specified in the
-   * remoteActionDelay pref.  If the pref is <= 0 then this function calls it
+   * httpRequestDelay pref.  If the pref is <= 0 then this function calls it
    * immediately.
    * This should help mitigate 503 errors if the pref is set.
    * @param {function} func The function to call.
    */
   delayedProcessQueue: function Sync_delayedProcessQueue(func) {
-    if (com.gContactSync.Preferences.mSyncPrefs.remoteActionDelay.value > 0) {
+    if (com.gContactSync.Preferences.mSyncPrefs.httpRequestDelay.value > 0) {
       setTimeout(func,
-                 com.gContactSync.Preferences.mSyncPrefs.remoteActionDelay.value);
+                 com.gContactSync.Preferences.mSyncPrefs.httpRequestDelay.value);
     } else {
       func.call();
     }
diff --git a/src/content/ThrottleTest.js b/src/content/ThrottleTest.js
new file mode 100644
index 0000000..e23f025
--- /dev/null
+++ b/src/content/ThrottleTest.js
@@ -0,0 +1,175 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is gContactSync.
+ *
+ * The Initial Developer of the Original Code is
+ * Josh Geenen <gcontactsync at pirules.org>.
+ * Portions created by the Initial Developer are Copyright (C) 2014
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if (!com) {
+  /** A generic wrapper variable */
+  var com = {};
+}
+
+if (!com.gContactSync) {
+  /** A wrapper for all GCS functions and variables */
+  com.gContactSync = {};
+}
+
+/**
+ * Runs a test to find the lowest necessary delay between requests to avoid 503 errors.
+ * @class
+ */
+com.gContactSync.ThrottleTest = {
+
+  /** Stores whether a test is in progress. */
+  mTestInProgress: false,
+
+  /** The number of iterations for the test. */
+  mIters: 100,
+
+  /**
+   * Begins a throttle test.
+   * @param aDelay {int} The delay to test.
+   */
+  start: function ThrottleTest_start(aDelay) {
+    if (this.mTestInProgress) {
+      com.gContactSync.alertError(com.gContactSync.StringBundle.getStr("throttleTestAlreadyRunning"));
+      return;
+    }
+    var abs = com.gContactSync.GAbManager.getSyncedAddressBooks(true);
+    if (!abs.length) {
+      com.gContactSync.alertError(com.gContactSync.StringBundle.getStr("throttleTestNoABFound"));
+      return;
+    }
+    this.mAB = abs[0].ab;
+    this.mUsername = abs[0].username;
+    this.mToken = com.gContactSync.LoginManager.getAuthToken(this.mUsername);
+    var abCard = this.mAB.getAllContacts()[0];
+    this.mURL = abCard.getValue("SelfURL");
+    this.mNumReceived = 0;
+    this.mNumErrors = 0;
+    this.mNum503s = 0;
+    this.mDelay = aDelay;
+    this.mNumSent = 0;
+    this.mTestInProgress = true;
+    com.gContactSync.Preferences.setSyncPref("statusBarText",
+                                             com.gContactSync.StringBundle.getStr("throttleTestTryingDelay") + " " +
+                                             com.gContactSync.ThrottleTest.mDelay + " ms.");
+    if (aDelay > 0) {
+      setTimeout(com.gContactSync.ThrottleTest.next, Math.max(10000, com.gContactSync.ThrottleTest.mDelay));
+    } else {
+      this.next();
+    }
+  },
+
+  /**
+   * Sends the next request asynchronously.
+   */
+  next: function ThrottleTest_next() {
+
+    var httpReq = new com.gContactSync.GHttpRequest("get",
+                                                    com.gContactSync.ThrottleTest.mToken,
+                                                    com.gContactSync.ThrottleTest.mURL,
+                                                    null,
+                                                    com.gContactSync.ThrottleTest.mUsername);
+    httpReq.addHeaderItem("If-Match", "*");
+    httpReq.mOnSuccess = com.gContactSync.ThrottleTest.onSuccess;
+    httpReq.mOnError   = com.gContactSync.ThrottleTest.onError;
+    httpReq.mOnOffline = com.gContactSync.ThrottleTest.onOffline;
+    httpReq.mOn503     = com.gContactSync.ThrottleTest.on503;
+    httpReq.send();
+    ++com.gContactSync.ThrottleTest.mNumSent;
+    if (com.gContactSync.ThrottleTest.mNumSent < com.gContactSync.ThrottleTest.mIters) {
+      setTimeout(com.gContactSync.ThrottleTest.next, com.gContactSync.ThrottleTest.mDelay);
+    }
+  },
+
+  /**
+   * Called when an HTTP request finishes successfully.
+   * @param {GHttpRequest} The HTTP request.
+   */
+  onSuccess: function ThrottleTest_onSuccess(httpReq) {
+    com.gContactSync.ThrottleTest.onReceive();
+  },
+
+  /**
+   * Called when an HTTP request returns an offline status.
+   * @param {GHttpRequest} The HTTP request.
+   */
+  onOffline: function ThrottleTest_onOffline(httpReq) {
+    com.gContactSync.Preferences.setSyncPref("statusBarText",
+                                             com.gContactSync.StringBundle.getStr("offlineStatusText")); 
+  },
+
+  /**
+   * Called when an HTTP request fails for an error other than a 503.
+   * @param {GHttpRequest} The HTTP request.
+   */
+  onError: function ThrottleTest_onError(httpReq) {
+    ++com.gContactSync.ThrottleTest.mNumErrors;
+    com.gContactSync.LOGGER.LOG_ERROR("Error while updating contact",
+                                      httpReq.responseText);
+    com.gContactSync.ThrottleTest.onReceive();
+  },
+
+  /**
+   * Called when an HTTP request fails for a 503.
+   * @param {GHttpRequest} The HTTP request.
+   */
+  on503: function ThrottleTest_on503(httpReq) {
+    ++com.gContactSync.ThrottleTest.mNum503s;
+    com.gContactSync.LOGGER.LOG_ERROR("503", httpReq.responseText);
+    com.gContactSync.ThrottleTest.onReceive();
+  },
+
+  /**
+   * Called when an HTTP request finishes.
+   * @param {GHttpRequest} The HTTP request.
+   */
+  onReceive: function ThrottleTest_onReceive() {
+    ++com.gContactSync.ThrottleTest.mNumReceived;
+    if (com.gContactSync.ThrottleTest.mNumReceived >= com.gContactSync.ThrottleTest.mIters) {
+      com.gContactSync.ThrottleTest.mTestInProgress = false;
+      if (com.gContactSync.ThrottleTest.mNumErrors) {
+        com.gContactSync.alertError(com.gContactSync.StringBundle.getStr("errorDuringThrottleTest"));
+      } else if (com.gContactSync.ThrottleTest.mNum503s) {
+        com.gContactSync.ThrottleTest.start(com.gContactSync.ThrottleTest.mDelay + 20);
+      } else {
+        com.gContactSync.alert(com.gContactSync.StringBundle.getStr("throttleTestMessage") + " " + com.gContactSync.ThrottleTest.mDelay);
+        com.gContactSync.Preferences.setSyncPref("httpRequestDelay", com.gContactSync.ThrottleTest.mDelay);
+        com.gContactSync.Preferences.setSyncPref("statusBarText",
+                                                 com.gContactSync.StringBundle.getStr("throttleTestComplete"));
+      }
+    }
+  }
+};
+
diff --git a/src/content/options.xul b/src/content/options.xul
index f67424c..3c869dc 100644
--- a/src/content/options.xul
+++ b/src/content/options.xul
@@ -222,6 +222,9 @@
       <preference id="httpRequestTimeout"
                   name="extensions.gContactSync.httpRequestTimeout"
                   type="int"/>
+      <preference id="httpRequestDelay"
+                  name="extensions.gContactSync.httpRequestDelay"
+                  type="int"/>
     </preferences>
     <vbox>
       <label value="&warning.value;"/>
@@ -287,6 +290,23 @@
                        maxlength="5"
                        maxwidth="60"/>
             </row>
+            <row align="center">
+              <label control="httpRequestDelay"
+                     value="&httpRequestDelay.value;"
+                     accesskey="&httpRequestDelay.accesskey;"/>
+            </row>
+            <row align="center">
+              <hbox>
+                <textbox preference="httpRequestDelay"
+                         id="httpRequestDelay"
+                         maxlength="5"
+                         maxwidth="60"/>
+                <button id="throttleTest"
+                        label="&throttleTest.label;"
+                        accesskey="&throttleTest.accesskey;"
+                        oncommand="com.gContactSync.ThrottleTest.start(0);"/>
+              </hbox>
+            </row>
           </rows>
         </grid>
       </groupbox>
@@ -347,6 +367,8 @@
           src="chrome://gcontactsync/content/Pref.js"/>
   <script type="application/x-javascript"
           src="chrome://gcontactsync/content/Preferences.js"/>
+  <script type="application/x-javascript"
+          src="chrome://gcontactsync/content/ThrottleTest.js"/>
   <stringbundleset id="stringbundleset">
     <stringbundle id="gContactSyncStringBundle"
                   src="chrome://gContactSync/locale/gcontactsync.properties"/>
diff --git a/src/content/synonyms.js b/src/content/synonyms.js
index 14eb2bf..bd18953 100644
--- a/src/content/synonyms.js
+++ b/src/content/synonyms.js
@@ -51,7 +51,7 @@ com.gContactSync.versionMinor   = "4";
 /** The release for the current version of gContactSync (ie 1 in 0.3.1a7) */
 com.gContactSync.versionRelease = "0";
 /** The suffix for the current version of gContactSync (ie a7 for Alpha 7) */
-com.gContactSync.versionSuffix  = "rc2";
+com.gContactSync.versionSuffix  = "rc3pre";
 /** The attribute where the dummy e-mail address is stored */
 com.gContactSync.dummyEmailName = "PrimaryEmail";
 
@@ -677,3 +677,48 @@ com.gContactSync.version04Upgrade = function gCS_version04Upgrade() {
   com.gContactSync.Preferences.setSyncPref("v04UpgradeNeeded", false);
   com.gContactSync.Preferences.setSyncPref("v04RCUpgradeNeeded", false);
 };
+
+com.gContactSync.test = function gCS_test() {
+
+  var ab = com.gContactSync.GAbManager.getGAbByName("gcontactsyncuser at gmail.com", true);
+  var abCard = ab.getAllContacts()[0];
+  var xml = com.gContactSync.ContactConverter.cardToAtomXML(abCard).xml;
+
+  com.gContactSync.string = com.gContactSync.serialize(xml);
+  com.gContactSync.editURL = abCard.getValue("EditURL");
+
+  com.gContactSync.num503s = 0;
+  com.gContactSync.delay = prompt("Delay?");
+  com.gContactSync.iters = prompt("Iters?");
+
+  com.gContactSync.onSuccess = function processUpdateSuccess(httpReq) {
+      com.gContactSync.LOGGER.LOG("Success");
+    };
+  com.gContactSync.onError = function processUpdateError(httpReq) {
+      com.gContactSync.LOGGER.LOG_ERROR('Error while updating contact',
+                                        httpReq.responseText);
+    };
+  com.gContactSync.on503 = function process503 (httpReq) { ++com.gContactSync.num503s; com.gContactSync.LOGGER.LOG_ERROR("503", httpReq.responseText); throw "503";};
+  com.gContactSync.token = com.gContactSync.LoginManager.getAuthToken("gcontactsyncuser at gmail.com");
+
+  com.gContactSync.i = 0;
+  com.gContactSync.test2();
+};
+
+com.gContactSync.test2 = function gCS_test2() {
+    var httpReq = new com.gContactSync.GHttpRequest("update",
+                                                    com.gContactSync.token,
+                                                    com.gContactSync.editURL,
+                                                    com.gContactSync.string,
+                                                    "gcontactsyncuser at gmail.com");
+    httpReq.addHeaderItem("If-Match", "*");
+    httpReq.mOnSuccess = com.gContactSync.onSuccess;
+    httpReq.mOnError   = com.gContactSync.onError;
+    httpReq.mOnOffline = com.gContactSync.Sync.mOfflineFunction;
+    httpReq.mOn503 = com.gContactSync.on503;
+    httpReq.send();
+
+    ++com.gContactSync.i;
+    if (com.gContactSync.i < com.gContactSync.iters) setTimeout(com.gContactSync.test2, com.gContactSync.delay);
+    else {alert(com.gContactSync.num503s);}
+};
diff --git a/src/defaults/preferences/gContactSync.js b/src/defaults/preferences/gContactSync.js
index c10b110..f07364c 100644
--- a/src/defaults/preferences/gContactSync.js
+++ b/src/defaults/preferences/gContactSync.js
@@ -84,14 +84,14 @@ pref("extensions.gContactSync.overrideGetCardForEmail", true);
 pref("extensions.gContactSync.syncPhoneticNames", true);
 // delay after uploading a contact photo to Google on new contacts, in ms
 pref("extensions.gContactSync.newContactPhotoDelay", 2000);
-// delay after adding, deleting, or updating a contact.  Can help mitigate 503 errors.
-pref("extensions.gContactSync.remoteActionDelay", 0);
 // Stores whether an upgrade is required from <0.4.0b1 to version 0.4
 pref("extensions.gContactSync.v04UpgradeNeeded", false);
 // Stores whether an upgrade is required from <0.4.0b5 and > 0.3.x to version 0.4
 pref("extensions.gContactSync.v04RCUpgradeNeeded", false);
 // Timeout in ms for HTTP requests, 0 means no timeout.
 pref("extensions.gContactSync.httpRequestTimeout", 0);
+// Delay between HTTP requests to mitigate 503 errors.
+pref("extensions.gContactSync.httpRequestDelay", 120);
 // extended properties to sync
 pref("extensions.gContactSync.extended1", "PreferMailFormat");
 pref("extensions.gContactSync.extended2", "AllowRemoteContent");
diff --git a/src/install.rdf b/src/install.rdf
index 3494098..172ba09 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -3,7 +3,7 @@
      xmlns:em="http://www.mozilla.org/2004/em-rdf#">
     <Description about="urn:mozilla:install-manifest">
         <em:id>gContactSync at pirules.net</em:id>
-        <em:version>0.4.0rc2</em:version>
+        <em:version>0.4.0rc3pre</em:version>
         <em:name>gContactSync</em:name>
         <em:description>Synchronizes Google Contacts with Thunderbird</em:description>
         <em:creator>Josh Geenen</em:creator>
diff --git a/src/locale/en-US/gcontactsync.properties b/src/locale/en-US/gcontactsync.properties
index e710e04..ab263de 100644
--- a/src/locale/en-US/gcontactsync.properties
+++ b/src/locale/en-US/gcontactsync.properties
@@ -324,3 +324,11 @@ version04UpgradeMessage=Converting your contacts for version 0.4 of gContactSync
 # Account setup wizard
 noAccountsFound=No Accounts Found
 abAlreadySynchronized=The requested address book is already being synchronized.  Please select or create a different address book.
+
+# Throttle test
+errorDuringThrottleTest=One or more unexpected errors occurred.  Please see the log for details.
+throttleTestMessage=Throttle test complete. New delay (ms):
+throttleTestComplete=Throttle test complete
+throttleTestNoABFound=You must synchronize at least one address book before running this test.
+throttleTestTryingDelay=Testing with a delay of:
+throttleTestAlreadyRunning=A test is already in progress.
diff --git a/src/locale/en-US/options.dtd b/src/locale/en-US/options.dtd
index a1733a5..32fe6c8 100644
--- a/src/locale/en-US/options.dtd
+++ b/src/locale/en-US/options.dtd
@@ -55,6 +55,8 @@
 <!ENTITY confirmDeleteThreshold.accesskey "d">
 <!ENTITY httpRequestTimeout.value         "HTTP Request Timeout (ms, 0 to disable) [0]">
 <!ENTITY httpRequestTimeout.accesskey     "H">
+<!ENTITY httpRequestDelay.value           "Delay between HTTP requests (ms, 0 to disable) [100]">
+<!ENTITY httpRequestDelay.accesskey       "l">
 <!ENTITY resetAll.label                   "Reset All Synced ABs">
 <!ENTITY resetAll.accesskey               "R">
 <!ENTITY cleanOldPrefs.label              "Clean Old AB Preferences">
@@ -63,3 +65,5 @@
 <!ENTITY cleanOldPhotos.accesskey         "P">
 <!ENTITY resetAllSettings.label           "Reset all gContactSync settings">
 <!ENTITY resetAllSettings.accesskey       "g">
+<!ENTITY throttleTest.label               "Run Throttle Test">
+<!ENTITY throttleTest.accesskey           "T">

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/gcontactsync.git



More information about the Pkg-mozext-commits mailing list