Bug 1197146 - Part 1: Prime dispatcher in listener to resolve promises. r=dburns, a=test-only
☠☠ backed out by 66e9b94c4066 ☠ ☠
authorAndreas Tolfsen <ato@mozilla.com>
Fri, 21 Aug 2015 15:00:29 +0100
changeset 288884 e4069d54d4b18b0acd84074cc2931dbb56a76ea6
parent 288883 32e63d193254018945f143e386270fce142ce818
child 288885 463f3471e857ef9d01e554b2f03797b9131c1bbc
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdburns, test-only
bugs1197146
milestone42.0a2
Bug 1197146 - Part 1: Prime dispatcher in listener to resolve promises. r=dburns, a=test-only 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.
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);