Bug 1577498 - Part 4: Batch webRequest events to reduce IPC overhead r=rpl

Differential Revision: https://phabricator.services.mozilla.com/D53332

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Tomislav Jovanovic 2019-11-20 19:20:26 +00:00
Родитель 3d48aef53b
Коммит 3e409cecde
3 изменённых файлов: 53 добавлений и 6 удалений

Просмотреть файл

@ -7,6 +7,12 @@
* This @file implements the child side of Conduits, an abstraction over
* Fission IPC for extension API subject. See {@link ConduitsParent.jsm}
* for more details about the overall design.
*
* @typedef {object} MessageData
* @prop {ConduitID} [target]
* @prop {ConduitID} [sender]
* @prop {boolean} query
* @prop {object} arg
*/
const EXPORTED_SYMBOLS = ["BaseConduit", "ConduitsChild"];
@ -47,7 +53,7 @@ class BaseConduit {
* @param {string} method
* @param {boolean} query Flag indicating a response is expected.
* @param {JSWindowActor} actor
* @param {{arg: object, sender: ConduitID}} data
* @param {MessageData} data
* @returns {Promise?}
*/
_send(method, query, actor, data) {
@ -144,9 +150,18 @@ class ConduitsChild extends JSWindowActorChild {
/**
* JSWindowActor method, routes the message to the target subject.
* @param {string} name
* @param {MessageData|MessageData[]} data
* @returns {Promise?}
*/
receiveMessage({ name, data: { target, arg, query, sender } }) {
receiveMessage({ name, data }) {
// Batch of webRequest events, run each and return results, ignoring errors.
if (Array.isArray(data)) {
let run = data => this.receiveMessage({ name, data });
return Promise.all(data.map(data => run(data).catch(Cu.reportError)));
}
let { target, arg, query, sender } = data;
let conduit = this.conduits.get(target);
if (!conduit) {
throw new Error(`${name} for closed conduit ${target}: ${uneval(arg)}`);

Просмотреть файл

@ -52,6 +52,8 @@ const { BaseConduit } = ChromeUtils.import(
"resource://gre/modules/ConduitsChild.jsm"
);
const BATCH_TIMEOUT_MS = 250;
/**
* Internal, keeps track of all parent and remote (child) conduits.
*/
@ -162,8 +164,13 @@ class BroadcastConduit extends BaseConduit {
if (!this.open) {
throw new Error(`send${method} on closed conduit ${this.id}`);
}
let sender = this.address;
let sender = this.id;
let { actor } = Hub.remotes.get(target);
if (method === "RunListener" && arg.path.startsWith("webRequest.")) {
return actor.batch(method, { target, arg, query, sender });
}
return super._send(method, query, actor, { target, arg, query, sender });
}
@ -188,10 +195,38 @@ class BroadcastConduit extends BaseConduit {
class ConduitsParent extends JSWindowActorParent {
constructor() {
super();
this.batchData = [];
this.batchPromise = null;
}
/**
* Group webRequest events to send them as a batch, reducing IPC overhead.
* @param {string} name
* @param {MessageData} data
*/
async batch(name, data) {
let num = this.batchData.length;
this.batchData.push(data);
if (!num) {
let resolve;
this.batchPromise = new Promise(r => (resolve = r));
let send = () => {
resolve(this.manager && this.sendQuery(name, this.batchData));
this.batchData = [];
};
ChromeUtils.idleDispatch(send, { timeout: BATCH_TIMEOUT_MS });
}
let results = await this.batchPromise;
return results && results[num];
}
/**
* JSWindowActor method, routes the message to the target subject.
* @param {string} name
* @param {MessageData} data
* @returns {Promise?}
*/
receiveMessage({ name, data: { arg, query, sender } }) {

Просмотреть файл

@ -1134,9 +1134,6 @@ ParentAPIManager = {
let { childId } = data;
let handlingUserInput = false;
// TODO: Bug 1587058 - Redesign webRequest event coelescing.
// let lowPriority = data.path.startsWith("webRequest.");
let listener = async (...listenerArgs) => {
let result = await this.conduit.queryRunListener(childId, {
childId,