Bug 1494632 - Convert WorkerClient to protocol.js front. r=jdescottes
authorAlexandre Poirot <poirot.alex@gmail.com>
Tue, 16 Oct 2018 09:39:11 +0000
changeset 489790 89308a0efe91b73daa395ca4af36727e5c151b4b
parent 489789 37d138b1e58b9c45ee3baef530bb133597b14eb3
child 489791 451ad77036b5068485a7affd6cc74768295d14e1
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersjdescottes
bugs1494632
milestone64.0a1
Bug 1494632 - Convert WorkerClient to protocol.js front. r=jdescottes MozReview-Commit-ID: BbtEReeG4v9 Depends on D7462 Differential Revision: https://phabricator.services.mozilla.com/D7463
devtools/client/debugger/test/mochitest/head.js
devtools/client/shared/test/helper_workers.js
devtools/shared/client/debugger-client.js
devtools/shared/client/moz.build
devtools/shared/client/worker-client.js
devtools/shared/fronts/targets/moz.build
devtools/shared/fronts/targets/worker.js
devtools/shared/specs/targets/worker.js
--- a/devtools/client/debugger/test/mochitest/head.js
+++ b/devtools/client/debugger/test/mochitest/head.js
@@ -1114,24 +1114,20 @@ function waitForWorkerListChanged(target
   return targetFront.once("workerListChanged");
 }
 
 function attachThread(workerClient, options) {
   info("Attaching to thread.");
   return workerClient.attachThread(options);
 }
 
-function waitForWorkerClose(workerClient) {
+async function waitForWorkerClose(workerClient) {
   info("Waiting for worker to close.");
-  return new Promise(function (resolve) {
-    workerClient.addOneTimeListener("close", function () {
-      info("Worker did close.");
-      resolve();
-    });
-  });
+  await workerClient.once("close");
+  info("Worker did close.");
 }
 
 function resume(threadClient) {
   info("Resuming thread.");
   return threadClient.resume();
 }
 
 function findSource(sources, url) {
--- a/devtools/client/shared/test/helper_workers.js
+++ b/devtools/client/shared/test/helper_workers.js
@@ -118,24 +118,20 @@ function attachWorker(tabClient, worker)
   return tabClient.attachWorker(worker.actor);
 }
 
 function attachThread(workerClient, options) {
   info("Attaching to thread.");
   return workerClient.attachThread(options);
 }
 
-function waitForWorkerClose(workerClient) {
+async function waitForWorkerClose(workerClient) {
   info("Waiting for worker to close.");
-  return new Promise(function(resolve) {
-    workerClient.addOneTimeListener("close", function() {
-      info("Worker did close.");
-      resolve();
-    });
-  });
+  await workerClient.once("close");
+  info("Worker did close.");
 }
 
 // Return a promise with a reference to jsterm, opening the split
 // console if necessary.  This cleans up the split console pref so
 // it won't pollute other tests.
 function getSplitConsole(toolbox, win) {
   if (!win) {
     win = toolbox.win;
--- a/devtools/shared/client/debugger-client.js
+++ b/devtools/shared/client/debugger-client.js
@@ -20,18 +20,18 @@ const {
 loader.lazyRequireGetter(this, "Authentication", "devtools/shared/security/auth");
 loader.lazyRequireGetter(this, "DebuggerSocket", "devtools/shared/security/socket", true);
 loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
 
 loader.lazyRequireGetter(this, "WebConsoleClient", "devtools/shared/webconsole/client", true);
 loader.lazyRequireGetter(this, "AddonClient", "devtools/shared/client/addon-client");
 loader.lazyRequireGetter(this, "RootClient", "devtools/shared/client/root-client");
 loader.lazyRequireGetter(this, "BrowsingContextFront", "devtools/shared/fronts/targets/browsing-context", true);
+loader.lazyRequireGetter(this, "WorkerTargetFront", "devtools/shared/fronts/targets/worker", true);
 loader.lazyRequireGetter(this, "ThreadClient", "devtools/shared/client/thread-client");
-loader.lazyRequireGetter(this, "WorkerClient", "devtools/shared/client/worker-client");
 loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/object-client");
 loader.lazyRequireGetter(this, "Pool", "devtools/shared/protocol", true);
 loader.lazyRequireGetter(this, "Front", "devtools/shared/protocol", true);
 
 // Retrieve the major platform version, i.e. if we are on Firefox 64.0a1, it will be 64.
 const PLATFORM_MAJOR_VERSION = AppConstants.MOZ_APP_VERSION.match(/\d+/)[0];
 
 // Define the minimum officially supported version of Firefox when connecting to a remote
@@ -375,32 +375,25 @@ DebuggerClient.prototype = {
       front = new BrowsingContextFront(this, { actor: targetActor });
       this._frontPool.manage(front);
     }
 
     const response = await front.attach();
     return [response, front];
   },
 
-  attachWorker: function(workerTargetActor) {
-    let workerClient = this._clients.get(workerTargetActor);
-    if (workerClient !== undefined) {
-      const response = {
-        from: workerClient.actor,
-        type: "attached",
-        url: workerClient.url
-      };
-      return promise.resolve([response, workerClient]);
+  attachWorker: async function(workerTargetActor) {
+    let front = this._frontPool.actor(workerTargetActor);
+    if (!front) {
+      front = new WorkerTargetFront(this, { actor: workerTargetActor });
+      this._frontPool.manage(front);
     }
 
-    return this.request({ to: workerTargetActor, type: "attach" }).then(response => {
-      workerClient = new WorkerClient(this, response);
-      this.registerClient(workerClient);
-      return [response, workerClient];
-    });
+    const response = await front.attach();
+    return [response, front];
   },
 
   /**
    * Attach to an addon target actor.
    *
    * @param string addonTargetActor
    *        The actor ID for the addon to attach.
    */
--- a/devtools/shared/client/moz.build
+++ b/devtools/shared/client/moz.build
@@ -15,10 +15,9 @@ DevToolsModules(
     'event-source.js',
     'long-string-client.js',
     'object-client.js',
     'property-iterator-client.js',
     'root-client.js',
     'source-client.js',
     'symbol-iterator-client.js',
     'thread-client.js',
-    'worker-client.js',
 )
deleted file mode 100644
--- a/devtools/shared/client/worker-client.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const {DebuggerClient} = require("devtools/shared/client/debugger-client");
-const eventSource = require("devtools/shared/client/event-source");
-loader.lazyRequireGetter(this, "ThreadClient", "devtools/shared/client/thread-client");
-
-function WorkerClient(client, form) {
-  this.client = client;
-  this._actor = form.from;
-  this._isClosed = false;
-  this._url = form.url;
-
-  this._onClose = this._onClose.bind(this);
-
-  this.addListener("close", this._onClose);
-
-  this.traits = {};
-}
-
-WorkerClient.prototype = {
-  get _transport() {
-    return this.client._transport;
-  },
-
-  get request() {
-    return this.client.request;
-  },
-
-  get actor() {
-    return this._actor;
-  },
-
-  get url() {
-    return this._url;
-  },
-
-  get isClosed() {
-    return this._isClosed;
-  },
-
-  detach: DebuggerClient.requester({ type: "detach" }, {
-    after: function(response) {
-      if (this.thread) {
-        this.client.unregisterClient(this.thread);
-      }
-      this.client.unregisterClient(this);
-      return response;
-    },
-  }),
-
-  attachThread: function(options = {}) {
-    if (this.thread) {
-      const response = [{
-        type: "connected",
-        threadActor: this.thread._actor,
-        consoleActor: this.consoleActor,
-      }, this.thread];
-      return response;
-    }
-
-    // The connect call on server doesn't attach the thread as of version 44.
-    return this.request({
-      to: this._actor,
-      type: "connect",
-      options,
-    }).then(connectResponse => {
-      return this.request({
-        to: connectResponse.threadActor,
-        type: "attach",
-        options,
-      }).then(attachResponse => {
-        this.thread = new ThreadClient(this, connectResponse.threadActor);
-        this.consoleActor = connectResponse.consoleActor;
-        this.client.registerClient(this.thread);
-
-        return [connectResponse, this.thread];
-      });
-    });
-  },
-
-  _onClose: function() {
-    this.removeListener("close", this._onClose);
-
-    if (this.thread) {
-      this.client.unregisterClient(this.thread);
-    }
-    this.client.unregisterClient(this);
-    this._isClosed = true;
-  },
-
-  reconfigure: function() {
-    return Promise.resolve();
-  },
-
-  events: ["close"]
-};
-
-eventSource(WorkerClient.prototype);
-
-module.exports = WorkerClient;
--- a/devtools/shared/fronts/targets/moz.build
+++ b/devtools/shared/fronts/targets/moz.build
@@ -1,9 +1,10 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DevToolsModules(
     'browsing-context.js',
+    'worker.js',
 )
new file mode 100644
--- /dev/null
+++ b/devtools/shared/fronts/targets/worker.js
@@ -0,0 +1,100 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+const {workerTargetSpec} = require("devtools/shared/specs/targets/worker");
+const protocol = require("devtools/shared/protocol");
+const {custom} = protocol;
+
+loader.lazyRequireGetter(this, "ThreadClient", "devtools/shared/client/thread-client");
+
+const WorkerTargetFront = protocol.FrontClassWithSpec(workerTargetSpec, {
+  initialize: function(client, form) {
+    protocol.Front.prototype.initialize.call(this, client, form);
+
+    this.thread = null;
+    this.traits = {};
+
+    // TODO: remove once ThreadClient becomes a front
+    this.client = client;
+
+    this._isClosed = false;
+
+    this.destroy = this.destroy.bind(this);
+    this.on("close", this.destroy);
+  },
+
+  get isClosed() {
+    return this._isClosed;
+  },
+
+  destroy: function() {
+    this.off("close", this.destroy);
+    this._isClosed = true;
+
+    if (this.thread) {
+      this.client.unregisterClient(this.thread);
+    }
+
+    this.unmanage(this);
+
+    protocol.Front.prototype.destroy.call(this);
+  },
+
+  attach: custom(async function() {
+    const response = await this._attach();
+
+    this.url = response.url;
+
+    return response;
+  }, {
+    impl: "_attach"
+  }),
+
+  detach: custom(async function() {
+    let response;
+    try {
+      response = await this._detach();
+    } catch (e) {
+      console.warn(`Error while detaching the worker target front: ${e.message}`);
+    }
+    this.destroy();
+    return response;
+  }, {
+    impl: "_detach"
+  }),
+
+  reconfigure: function() {
+    // Toolbox and options panel are calling this method but Worker Target can't be
+    // reconfigured. So we ignore this call here.
+    return Promise.resolve();
+  },
+
+  attachThread: async function(options = {}) {
+    if (this.thread) {
+      const response = [{
+        type: "connected",
+        threadActor: this.thread._actor,
+        consoleActor: this.consoleActor,
+      }, this.thread];
+      return response;
+    }
+
+    // The connect call on server doesn't attach the thread as of version 44.
+    const connectResponse = await this.connect(options);
+    await this.client.request({
+      to: connectResponse.threadActor,
+      type: "attach",
+      options,
+    });
+    this.thread = new ThreadClient(this, connectResponse.threadActor);
+    this.consoleActor = connectResponse.consoleActor;
+    this.client.registerClient(this.thread);
+
+    return [connectResponse, this.thread];
+  },
+
+});
+
+exports.WorkerTargetFront = WorkerTargetFront;
--- a/devtools/shared/specs/targets/worker.js
+++ b/devtools/shared/specs/targets/worker.js
@@ -23,11 +23,24 @@ const workerTargetSpec = generateActorSp
       },
       response: RetVal("json")
     },
     push: {
       request: {},
       response: RetVal("json")
     },
   },
+
+  events: {
+    // WorkerTargetActor still uses old sendActorEvent function,
+    // but it should use emit instead.
+    close: {
+      type: "close",
+    },
+    // newSource is being sent by ThreadActor in the name of its parent,
+    // i.e. WorkerTargetActor
+    newSource: {
+      type: "newSource",
+    }
+  }
 });
 
 exports.workerTargetSpec = workerTargetSpec;