Bug 1435000 - Refactor client engine queue to use AsyncQueueCaller r=eoger
authorCarol Ng <cng@mozilla.com>
Tue, 29 May 2018 14:30:22 -0400
changeset 420322 57b10eb3ea6f4594c5efe7c1e2d8ee4cae3fe8b9
parent 420321 3cb69bac2eac6758496c4584412274b44da0f557
child 420323 7f3ed39073e6f0dea1b7f45694d866b4be58298b
push id34070
push userncsoregi@mozilla.com
push dateWed, 30 May 2018 09:24:28 +0000
treeherdermozilla-central@c094fc31b95f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerseoger
bugs1435000
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1435000 - Refactor client engine queue to use AsyncQueueCaller r=eoger MozReview-Commit-ID: JRWHktfqGMQ
services/common/async.js
services/sync/modules/engines/clients.js
--- a/services/common/async.js
+++ b/services/common/async.js
@@ -158,19 +158,20 @@ class AsyncQueueCaller {
   /**
    * /!\ Never await on another function that calls enqueueCall /!\
    *     on the same queue or we will deadlock.
    */
   enqueueCall(func) {
     this._queue = (async () => {
       await this._queue;
       try {
-        await func();
+        return await func();
       } catch (e) {
         this._log.error(e);
+        return false;
       }
     })();
   }
 
   promiseCallsComplete() {
     return this._queue;
   }
 }
--- a/services/sync/modules/engines/clients.js
+++ b/services/sync/modules/engines/clients.js
@@ -81,17 +81,17 @@ Utils.deferGetSet(ClientsRec,
                    "formfactor", "os", "appPackage", "application", "device",
                    "fxaDeviceId"]);
 
 
 function ClientEngine(service) {
   SyncEngine.call(this, "Clients", service);
 
   this.fxAccounts = fxAccounts;
-  this.addClientCommandQueue = Promise.resolve();
+  this.addClientCommandQueue = Async.asyncQueueCaller(this._log);
   Utils.defineLazyIDProperty(this, "localID", "services.sync.client.GUID");
 }
 ClientEngine.prototype = {
   __proto__: SyncEngine.prototype,
   _storeObj: ClientStore,
   _recordObj: ClientsRec,
   _trackerObj: ClientsTracker,
   allowSkippedRecord: false,
@@ -288,18 +288,17 @@ ClientEngine.prototype = {
 
   async removeLocalCommand(command) {
     // the implementation of this engine is such that adding a command to
     // the local client is how commands are deleted! ¯\_(ツ)_/¯
     await this._addClientCommand(this.localID, command);
   },
 
   async _addClientCommand(clientId, command) {
-    return this.addClientCommandQueue = (async () => {
-      await this.addClientCommandQueue;
+    this.addClientCommandQueue.enqueueCall(async () => {
       try {
         const localCommands = await this._readCommands();
         const localClientCommands = localCommands[clientId] || [];
         const remoteClient = this._store._remoteClients[clientId];
         let remoteClientCommands = [];
         if (remoteClient && remoteClient.commands) {
           remoteClientCommands = remoteClient.commands;
         }
@@ -310,17 +309,19 @@ ClientEngine.prototype = {
         localCommands[clientId] = localClientCommands.concat(command);
         await this._saveCommands(localCommands);
         return true;
       } catch (e) {
         // Failing to save a command should not "break the queue" of pending operations.
         this._log.error(e);
         return false;
       }
-    })();
+    });
+
+    return this.addClientCommandQueue.promiseCallsComplete();
   },
 
   async _removeClientCommands(clientId) {
     const allCommands = await this._readCommands();
     delete allCommands[clientId];
     await this._saveCommands(allCommands);
   },