Bug 1509267 - Cleanup Remote Settings worker when inactive r=glasserc,dthayer

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Mathieu Leplatre 2019-05-16 09:10:34 +00:00
parent 3542b77c41
commit 929e1fb8fd

View File

@ -7,22 +7,37 @@
/**
* Interface to a dedicated thread handling for Remote Settings heavy operations.
*/
// ChromeUtils.import("resource://gre/modules/PromiseWorker.jsm", this);
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const { setTimeout, clearTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm");
var EXPORTED_SYMBOLS = ["RemoteSettingsWorker"];
XPCOMUtils.defineLazyPreferenceGetter(this, "gMaxIdleMilliseconds",
"services.settings.worker_idle_max_milliseconds",
30 * 1000 // Default of 30 seconds.
);
class Worker {
constructor(source) {
this.worker = new ChromeWorker(source);
this.worker.onmessage = this._onWorkerMessage.bind(this);
this.source = source;
this.worker = null;
this.callbacks = new Map();
this.lastCallbackId = 0;
this.idleTimeoutId = null;
}
async _execute(method, args = []) {
return new Promise(async (resolve, reject) => {
// (Re)instantiate the worker if it was terminated.
if (!this.worker) {
this.worker = new ChromeWorker(this.source);
this.worker.onmessage = this._onWorkerMessage.bind(this);
}
// New activity: reset the idle timer.
if (this.idleTimeoutId) {
clearTimeout(this.idleTimeoutId);
}
return new Promise((resolve, reject) => {
const callbackId = ++this.lastCallbackId;
this.callbacks.set(callbackId, [resolve, reject]);
this.worker.postMessage({ callbackId, method, args });
@ -38,6 +53,16 @@ class Worker {
resolve(result);
}
this.callbacks.delete(callbackId);
// Terminate the worker when it's unused for some time.
// But don't terminate it if an operation is pending.
if (this.callbacks.length == 0) {
this.idleTimeoutId = setTimeout(() => {
this.worker.terminate();
this.worker = null;
this.idleTimeoutId = null;
}, gMaxIdleMilliseconds);
}
}
async canonicalStringify(localRecords, remoteRecords, timestamp) {