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 497192 89308a0efe91b73daa395ca4af36727e5c151b4b
parent 497191 37d138b1e58b9c45ee3baef530bb133597b14eb3
child 497193 451ad77036b5068485a7affd6cc74768295d14e1
push id9996
push userarchaeopteryx@coole-files.de
push dateThu, 18 Oct 2018 18:37:15 +0000
treeherdermozilla-beta@8efe26839243 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes
bugs1494632
milestone64.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 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;