Bug 1958325 - Move TimedPromise to remote/shared/Sync.sys.mjs r=webdriver-reviewers,jdescottes
We will use it in the BiDi module in the next commit. Drop the unused TimedPromise import from telemetry test altogether. Differential Revision: https://phabricator.services.mozilla.com/D247041
This commit is contained in:
committed by
jdescottes@mozilla.com
parent
3939728961
commit
82e49344b2
@@ -18,10 +18,6 @@ const gTestRoot = getRootDirectory(gTestPath).replace(
|
||||
"http://mochi.test:8888"
|
||||
);
|
||||
|
||||
const { TimedPromise } = ChromeUtils.importESModule(
|
||||
"chrome://remote/content/marionette/sync.sys.mjs"
|
||||
);
|
||||
|
||||
async function run_test(count) {
|
||||
const histogram = TelemetryTestUtils.getAndClearHistogram(
|
||||
"FX_NUMBER_OF_UNIQUE_SITE_ORIGINS_ALL_TABS"
|
||||
|
||||
@@ -46,7 +46,7 @@ what you need:
|
||||
|
||||
```javascript
|
||||
const { TimedPromise } = ChromeUtils.importESModule(
|
||||
"chrome://remote/content/marionette/sync.sys.mjs"
|
||||
"chrome://remote/content/shared/Sync.sys.mjs"
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
event: "chrome://remote/content/shared/webdriver/Event.sys.mjs",
|
||||
Log: "chrome://remote/content/shared/Log.sys.mjs",
|
||||
pprint: "chrome://remote/content/shared/Format.sys.mjs",
|
||||
TimedPromise: "chrome://remote/content/marionette/sync.sys.mjs",
|
||||
TimedPromise: "chrome://remote/content/shared/Sync.sys.mjs",
|
||||
});
|
||||
|
||||
ChromeUtils.defineLazyGetter(lazy, "logger", () =>
|
||||
|
||||
@@ -12,7 +12,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
PageLoadStrategy:
|
||||
"chrome://remote/content/shared/webdriver/Capabilities.sys.mjs",
|
||||
ProgressListener: "chrome://remote/content/shared/Navigate.sys.mjs",
|
||||
TimedPromise: "chrome://remote/content/marionette/sync.sys.mjs",
|
||||
TimedPromise: "chrome://remote/content/shared/Sync.sys.mjs",
|
||||
truncate: "chrome://remote/content/shared/Format.sys.mjs",
|
||||
});
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
* 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/. */
|
||||
|
||||
import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
|
||||
|
||||
const lazy = {};
|
||||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
@@ -17,8 +15,6 @@ ChromeUtils.defineLazyGetter(lazy, "logger", () =>
|
||||
|
||||
const { TYPE_ONE_SHOT, TYPE_REPEATING_SLACK } = Ci.nsITimer;
|
||||
|
||||
const PROMISE_TIMEOUT = AppConstants.DEBUG ? 4500 : 1500;
|
||||
|
||||
/**
|
||||
* Runs a Promise-like function off the main thread until it is resolved
|
||||
* through ``resolve`` or ``rejected`` callbacks. The function is
|
||||
@@ -135,93 +131,6 @@ export function PollPromise(func, { timeout = null, interval = 10 } = {}) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the timed, eventual completion (or failure) of an
|
||||
* asynchronous operation, and its resulting value.
|
||||
*
|
||||
* In contrast to a regular Promise, it times out after ``timeout``.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* Function to run, which will have its ``reject``
|
||||
* callback invoked after the ``timeout`` duration is reached.
|
||||
* It is given two callbacks: ``resolve(value)`` and
|
||||
* ``reject(error)``.
|
||||
* @param {object=} options
|
||||
* @param {string} options.errorMessage
|
||||
* Message to use for the thrown error.
|
||||
* @param {number=} options.timeout
|
||||
* ``condition``'s ``reject`` callback will be called
|
||||
* after this timeout, given in milliseconds.
|
||||
* By default 1500 ms in an optimised build and 4500 ms in
|
||||
* debug builds.
|
||||
* @param {Error=} options.throws
|
||||
* When the ``timeout`` is hit, this error class will be
|
||||
* thrown. If it is null, no error is thrown and the promise is
|
||||
* instead resolved on timeout with a TimeoutError.
|
||||
*
|
||||
* @returns {Promise.<*>}
|
||||
* Timed promise.
|
||||
*
|
||||
* @throws {TypeError}
|
||||
* If `timeout` is not a number.
|
||||
* @throws {RangeError}
|
||||
* If `timeout` is not an unsigned integer.
|
||||
*/
|
||||
export function TimedPromise(fn, options = {}) {
|
||||
const {
|
||||
errorMessage = "TimedPromise timed out",
|
||||
timeout = PROMISE_TIMEOUT,
|
||||
throws = lazy.error.TimeoutError,
|
||||
} = options;
|
||||
|
||||
const timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
|
||||
if (typeof fn != "function") {
|
||||
throw new TypeError();
|
||||
}
|
||||
if (typeof timeout != "number") {
|
||||
throw new TypeError();
|
||||
}
|
||||
if (!Number.isInteger(timeout) || timeout < 0) {
|
||||
throw new RangeError();
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let trace;
|
||||
|
||||
// Reject only if |throws| is given. Otherwise it is assumed that
|
||||
// the user is OK with the promise timing out.
|
||||
let bail = () => {
|
||||
const message = `${errorMessage} after ${timeout} ms`;
|
||||
if (throws !== null) {
|
||||
let err = new throws(message);
|
||||
reject(err);
|
||||
} else {
|
||||
lazy.logger.warn(message, trace);
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
|
||||
trace = lazy.error.stack();
|
||||
timer.initWithCallback({ notify: bail }, timeout, TYPE_ONE_SHOT);
|
||||
|
||||
try {
|
||||
fn(resolve, reject);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}).then(
|
||||
res => {
|
||||
timer.cancel();
|
||||
return res;
|
||||
},
|
||||
err => {
|
||||
timer.cancel();
|
||||
throw err;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pauses for the given duration.
|
||||
*
|
||||
|
||||
@@ -6,7 +6,6 @@ const {
|
||||
DebounceCallback,
|
||||
PollPromise,
|
||||
Sleep,
|
||||
TimedPromise,
|
||||
waitForMessage,
|
||||
waitForObserverTopic,
|
||||
} = ChromeUtils.importESModule(
|
||||
@@ -169,57 +168,6 @@ add_task(async function test_PollPromise_interval() {
|
||||
equal(2, nevals);
|
||||
});
|
||||
|
||||
add_task(function test_TimedPromise_funcTypes() {
|
||||
for (let type of ["foo", 42, null, undefined, true, [], {}]) {
|
||||
Assert.throws(() => new TimedPromise(type), /TypeError/);
|
||||
}
|
||||
new TimedPromise(resolve => resolve());
|
||||
new TimedPromise(function (resolve) {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function test_TimedPromise_timeoutTypes() {
|
||||
for (let timeout of ["foo", null, true, [], {}]) {
|
||||
Assert.throws(
|
||||
() => new TimedPromise(resolve => resolve(), { timeout }),
|
||||
/TypeError/
|
||||
);
|
||||
}
|
||||
for (let timeout of [1.2, -1]) {
|
||||
Assert.throws(
|
||||
() => new TimedPromise(resolve => resolve(), { timeout }),
|
||||
/RangeError/
|
||||
);
|
||||
}
|
||||
new TimedPromise(resolve => resolve(), { timeout: 42 });
|
||||
});
|
||||
|
||||
add_task(async function test_TimedPromise_errorMessage() {
|
||||
try {
|
||||
await new TimedPromise(() => {}, { timeout: 0 });
|
||||
ok(false, "Expected Timeout error not raised");
|
||||
} catch (e) {
|
||||
ok(
|
||||
e.message.includes("TimedPromise timed out after"),
|
||||
"Expected default error message found"
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
await new TimedPromise(() => {}, {
|
||||
errorMessage: "Not found",
|
||||
timeout: 0,
|
||||
});
|
||||
ok(false, "Expected Timeout error not raised");
|
||||
} catch (e) {
|
||||
ok(
|
||||
e.message.includes("Not found after"),
|
||||
"Expected custom error message found"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function test_Sleep() {
|
||||
await Sleep(0);
|
||||
for (let type of ["foo", true, null, undefined]) {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* 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/. */
|
||||
|
||||
import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
|
||||
|
||||
const lazy = {};
|
||||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
@@ -11,6 +13,8 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
|
||||
const { TYPE_ONE_SHOT, TYPE_REPEATING_SLACK } = Ci.nsITimer;
|
||||
|
||||
const PROMISE_TIMEOUT = AppConstants.DEBUG ? 4500 : 1500;
|
||||
|
||||
ChromeUtils.defineLazyGetter(lazy, "logger", () =>
|
||||
lazy.Log.get(lazy.Log.TYPES.REMOTE_AGENT)
|
||||
);
|
||||
@@ -334,3 +338,90 @@ export function PollPromise(func, options = {}) {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the timed, eventual completion (or failure) of an
|
||||
* asynchronous operation, and its resulting value.
|
||||
*
|
||||
* In contrast to a regular Promise, it times out after ``timeout``.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* Function to run, which will have its ``reject``
|
||||
* callback invoked after the ``timeout`` duration is reached.
|
||||
* It is given two callbacks: ``resolve(value)`` and
|
||||
* ``reject(error)``.
|
||||
* @param {object=} options
|
||||
* @param {string} options.errorMessage
|
||||
* Message to use for the thrown error.
|
||||
* @param {number=} options.timeout
|
||||
* ``condition``'s ``reject`` callback will be called
|
||||
* after this timeout, given in milliseconds.
|
||||
* By default 1500 ms in an optimised build and 4500 ms in
|
||||
* debug builds.
|
||||
* @param {Error=} options.throws
|
||||
* When the ``timeout`` is hit, this error class will be
|
||||
* thrown. If it is null, no error is thrown and the promise is
|
||||
* instead resolved on timeout with a TimeoutError.
|
||||
*
|
||||
* @returns {Promise.<*>}
|
||||
* Timed promise.
|
||||
*
|
||||
* @throws {TypeError}
|
||||
* If `timeout` is not a number.
|
||||
* @throws {RangeError}
|
||||
* If `timeout` is not an unsigned integer.
|
||||
*/
|
||||
export function TimedPromise(fn, options = {}) {
|
||||
const {
|
||||
errorMessage = "TimedPromise timed out",
|
||||
timeout = PROMISE_TIMEOUT,
|
||||
throws = lazy.error.TimeoutError,
|
||||
} = options;
|
||||
|
||||
const timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
|
||||
if (typeof fn != "function") {
|
||||
throw new TypeError();
|
||||
}
|
||||
if (typeof timeout != "number") {
|
||||
throw new TypeError();
|
||||
}
|
||||
if (!Number.isInteger(timeout) || timeout < 0) {
|
||||
throw new RangeError();
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let trace;
|
||||
|
||||
// Reject only if |throws| is given. Otherwise it is assumed that
|
||||
// the user is OK with the promise timing out.
|
||||
let bail = () => {
|
||||
const message = `${errorMessage} after ${timeout} ms`;
|
||||
if (throws !== null) {
|
||||
let err = new throws(message);
|
||||
reject(err);
|
||||
} else {
|
||||
lazy.logger.warn(message, trace);
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
|
||||
trace = lazy.error.stack();
|
||||
timer.initWithCallback({ notify: bail }, timeout, TYPE_ONE_SHOT);
|
||||
|
||||
try {
|
||||
fn(resolve, reject);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}).then(
|
||||
res => {
|
||||
timer.cancel();
|
||||
return res;
|
||||
},
|
||||
err => {
|
||||
timer.cancel();
|
||||
throw err;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
generateUUID: "chrome://remote/content/shared/UUID.sys.mjs",
|
||||
Log: "chrome://remote/content/shared/Log.sys.mjs",
|
||||
TabManager: "chrome://remote/content/shared/TabManager.sys.mjs",
|
||||
TimedPromise: "chrome://remote/content/marionette/sync.sys.mjs",
|
||||
TimedPromise: "chrome://remote/content/shared/Sync.sys.mjs",
|
||||
UserContextManager:
|
||||
"chrome://remote/content/shared/UserContextManager.sys.mjs",
|
||||
waitForObserverTopic: "chrome://remote/content/marionette/sync.sys.mjs",
|
||||
|
||||
@@ -6,8 +6,13 @@ const { setTimeout } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/Timer.sys.mjs"
|
||||
);
|
||||
|
||||
const { AnimationFramePromise, Deferred, EventPromise, PollPromise } =
|
||||
ChromeUtils.importESModule("chrome://remote/content/shared/Sync.sys.mjs");
|
||||
const {
|
||||
AnimationFramePromise,
|
||||
Deferred,
|
||||
EventPromise,
|
||||
PollPromise,
|
||||
TimedPromise,
|
||||
} = ChromeUtils.importESModule("chrome://remote/content/shared/Sync.sys.mjs");
|
||||
|
||||
const { Log } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/Log.sys.mjs"
|
||||
@@ -453,3 +458,54 @@ add_task(async function test_PollPromise_resolve() {
|
||||
Assert.equal(appender.messages[0].level, Log.Level.Warn);
|
||||
Assert.equal(appender.messages[0].message, "PollingFailed after 100 ms");
|
||||
});
|
||||
|
||||
add_task(function test_TimedPromise_funcTypes() {
|
||||
for (let type of ["foo", 42, null, undefined, true, [], {}]) {
|
||||
Assert.throws(() => new TimedPromise(type), /TypeError/);
|
||||
}
|
||||
new TimedPromise(resolve => resolve());
|
||||
new TimedPromise(function (resolve) {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function test_TimedPromise_timeoutTypes() {
|
||||
for (let timeout of ["foo", null, true, [], {}]) {
|
||||
Assert.throws(
|
||||
() => new TimedPromise(resolve => resolve(), { timeout }),
|
||||
/TypeError/
|
||||
);
|
||||
}
|
||||
for (let timeout of [1.2, -1]) {
|
||||
Assert.throws(
|
||||
() => new TimedPromise(resolve => resolve(), { timeout }),
|
||||
/RangeError/
|
||||
);
|
||||
}
|
||||
new TimedPromise(resolve => resolve(), { timeout: 42 });
|
||||
});
|
||||
|
||||
add_task(async function test_TimedPromise_errorMessage() {
|
||||
try {
|
||||
await new TimedPromise(() => {}, { timeout: 0 });
|
||||
ok(false, "Expected Timeout error not raised");
|
||||
} catch (e) {
|
||||
ok(
|
||||
e.message.includes("TimedPromise timed out after"),
|
||||
"Expected default error message found"
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
await new TimedPromise(() => {}, {
|
||||
errorMessage: "Not found",
|
||||
timeout: 0,
|
||||
});
|
||||
ok(false, "Expected Timeout error not raised");
|
||||
} catch (e) {
|
||||
ok(
|
||||
e.message.includes("Not found after"),
|
||||
"Expected custom error message found"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user