Bug 1642295 - Stop and start resource listening when switching targets r=ochameau

Depends on D86964

Differential Revision: https://phabricator.services.mozilla.com/D86965
This commit is contained in:
Julian Descottes 2020-08-19 15:27:22 +00:00
Родитель 8aecb1e6df
Коммит b34da59978
1 изменённых файлов: 63 добавлений и 29 удалений

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

@ -203,12 +203,27 @@ class ResourceWatcher {
* composed of a BrowsingContextTargetFront or ContentProcessTargetFront.
*/
async _onTargetAvailable({ targetFront, isTargetSwitching }) {
const resources = [];
if (isTargetSwitching) {
this._onWillNavigate(targetFront);
// WatcherActor currently only watches additional frame targets and
// explicitely ignores top level one that may be created when navigating
// to a new process.
// In order to keep working resources that are being watched via the
// Watcher actor, we have to unregister and re-register the resource
// types. This will force calling `watchTargetResources` on the new top
// level target.
for (const resourceType of this._listenerCount.keys()) {
await this._stopListening(resourceType, { bypassListenerCount: true });
resources.push(resourceType);
}
}
targetFront.on("will-navigate", () => this._onWillNavigate(targetFront));
// If we are target switching, we already stop & start listening to all the
// currently monitored resources.
if (!isTargetSwitching) {
// For each resource type...
for (const resourceType of Object.values(ResourceWatcher.TYPES)) {
// ...which has at least one listener...
@ -223,6 +238,8 @@ class ResourceWatcher {
}
await this._watchResourcesForTarget(targetFront, resourceType);
}
}
// Compared to the TargetList and Watcher.watchTargets,
// We do call Watcher.watchResources, but the events are fired on the target.
// That's because the Watcher runs in the parent process/main thread, while resources
@ -239,6 +256,12 @@ class ResourceWatcher {
"resource-destroyed-form",
this._onResourceDestroyed.bind(this, { targetFront })
);
if (isTargetSwitching) {
for (const resourceType of resources) {
await this._startListening(resourceType, { bypassListenerCount: true });
}
}
}
/**
@ -423,8 +446,14 @@ class ResourceWatcher {
* @param {String} resourceType
* One string of ResourceWatcher.TYPES, which designates the types of resources
* to be listened.
* @param {Object}
* - {Boolean} bypassListenerCount
* Pass true to avoid checking/updating the listenersCount map.
* Exclusively used when target switching, to stop & start listening
* to all resources.
*/
async _startListening(resourceType) {
async _startListening(resourceType, { bypassListenerCount = false } = {}) {
if (!bypassListenerCount) {
let listeners = this._listenerCount.get(resourceType) || 0;
listeners++;
this._listenerCount.set(resourceType, listeners);
@ -432,6 +461,7 @@ class ResourceWatcher {
if (listeners > 1) {
return;
}
}
// If the server supports the Watcher API and the Watcher supports
// this resource type, use this API
@ -485,8 +515,11 @@ class ResourceWatcher {
/**
* Reverse of _startListening. Stop listening for a given type of resource.
* For backward compatibility, we unregister from each individual target.
*
* See _startListening for parameters description.
*/
_stopListening(resourceType) {
_stopListening(resourceType, { bypassListenerCount = false } = {}) {
if (!bypassListenerCount) {
let listeners = this._listenerCount.get(resourceType);
if (!listeners || listeners <= 0) {
throw new Error(
@ -498,6 +531,7 @@ class ResourceWatcher {
if (listeners > 0) {
return;
}
}
// Clear the cached resources of the type.
this._cache = this._cache.filter(