Bug 1197146: Part 1: Prime dispatcher in listener to resolve promises
authorAndreas Tolfsen <ato@mozilla.com>
Fri, 21 Aug 2015 15:00:29 +0100
changeset 259259 1e582796c14f070c9e8c9fa2523e55eef11e763a
parent 259258 8b3601d4fce4521cad1752f7be418ccd5fc71604
child 259260 dda01c42607b0c7b6abd5eb1fed3280e4dfd999a
push id29275
push userryanvm@gmail.com
push dateTue, 25 Aug 2015 20:52:52 +0000
treeherdermozilla-central@c46370eea81a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1197146
milestone43.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 1197146: Part 1: Prime dispatcher in listener to resolve promises Because of the asynchronous behaviour of some internal utilities, such as ElementManager, we need to employ promises to create a bridge over them and the synchronous returning functions. r=dburns
testing/marionette/listener.js
--- a/testing/marionette/listener.js
+++ b/testing/marionette/listener.js
@@ -12,16 +12,17 @@ let loader = Cc["@mozilla.org/moz/jssubs
 
 loader.loadSubScript("chrome://marionette/content/simpletest.js");
 loader.loadSubScript("chrome://marionette/content/common.js");
 loader.loadSubScript("chrome://marionette/content/actions.js");
 Cu.import("chrome://marionette/content/elements.js");
 Cu.import("chrome://marionette/content/error.js");
 Cu.import("resource://gre/modules/FileUtils.jsm");
 Cu.import("resource://gre/modules/NetUtil.jsm");
+Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 let utils = {};
 utils.window = content;
 // Load Event/ChromeUtils for use with JS scripts:
 loader.loadSubScript("chrome://marionette/content/EventUtils.js", utils);
 loader.loadSubScript("chrome://marionette/content/ChromeUtils.js", utils);
 loader.loadSubScript("chrome://marionette/content/atoms.js", utils);
 loader.loadSubScript("chrome://marionette/content/sendkeys.js", utils);
@@ -142,35 +143,44 @@ function emitTouchEventForIFrame(message
       typeForUtils = domWindowUtils.TOUCH_CONTACT;
       break;
   }
   domWindowUtils.sendNativeTouchPoint(identifier, typeForUtils,
     Math.round(message.screenX * ratio), Math.round(message.screenY * ratio),
     message.force, 90);
 }
 
+// Eventually we will not have a closure for every single command, but
+// use a generic dispatch for all listener commands.
+//
+// Perhaps one could even conceive having a separate instance of
+// CommandProcessor for the listener, because the code is mostly the same.
 function dispatch(fn) {
   return function(msg) {
     let id = msg.json.command_id;
-    try {
+
+    let req = Task.spawn(function*() {
       let rv;
       if (typeof msg.json == "undefined" || msg.json instanceof Array) {
-        rv = fn.apply(null, msg.json);
+        return yield fn.apply(null, msg.json);
       } else {
-        rv = fn(msg.json);
+        return yield fn(msg.json);
       }
+    });
 
+    let okOrValueResponse = rv => {
       if (typeof rv == "undefined") {
         sendOk(id);
       } else {
         sendResponse({value: rv}, id);
       }
-    } catch (e) {
-      sendError(e, id);
-    }
+    };
+
+    req.then(okOrValueResponse, err => sendError(err, id))
+        .catch(error.report);
   };
 }
 
 /**
  * Add a message listener that's tied to our listenerId.
  */
 function addMessageListenerId(messageName, handler) {
   addMessageListener(messageName + listenerId, handler);