mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1648631: Part 1 - Make L10nRegistryService._synchronizeSharedData() explicitly flush and convert source registration to accept arrays; r=zbraniecki
Setting a key/value pair on the parent process message manager's `sharedData` initiates a pending runnable that runs at **idle priority**. If the current thread never gets a chance to idle, then those registry changes will never be synchronized. This patch adds an explicit flush so that `_synchronizeSharedData` does indeed actually synchronize. We replace the scalar `registerSource`, `updateSource`, and `removeSource` with variants that accept arrays instead. This allows us to process multiple registration changes while deferring the synchronization until the entire list has been processed. The scalar variants were removed to future-proof against perf issues. Differential Revision: https://phabricator.services.mozilla.com/D81243
This commit is contained in:
parent
57e09be6aa
commit
391ecb8515
@ -105,12 +105,13 @@ class L10nRegistryService {
|
||||
// - langpack-{locale}
|
||||
//
|
||||
// This should ensure that they're returned in the correct order.
|
||||
let fileSources = [];
|
||||
for (let {entry, value} of Services.catMan.enumerateCategory("l10n-registry")) {
|
||||
if (!this.hasSource(entry)) {
|
||||
const source = new FileSource(entry, locales, value);
|
||||
this.registerSource(source);
|
||||
fileSources.push(new FileSource(entry, locales, value));
|
||||
}
|
||||
}
|
||||
this.registerSources(fileSources);
|
||||
} else {
|
||||
this._setSourcesFromSharedData();
|
||||
Services.cpmm.sharedData.addEventListener("change", this);
|
||||
@ -201,49 +202,66 @@ class L10nRegistryService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new resource source to the L10nRegistry.
|
||||
* Adds new resource source(s) to the L10nRegistry.
|
||||
*
|
||||
* @param {FileSource} source
|
||||
* Notice: Each invocation of this method flushes any changes out to extant
|
||||
* content processes, which is expensive. Please coalesce multiple
|
||||
* registrations into a single sources array and then call this method once.
|
||||
*
|
||||
* @param {Array<FileSource>} sources
|
||||
*/
|
||||
registerSource(source) {
|
||||
if (this.hasSource(source.name)) {
|
||||
throw new Error(`Source with name "${source.name}" already registered.`);
|
||||
registerSources(sources) {
|
||||
for (const source of sources) {
|
||||
if (this.hasSource(source.name)) {
|
||||
throw new Error(`Source with name "${source.name}" already registered.`);
|
||||
}
|
||||
this.sources.set(source.name, source);
|
||||
}
|
||||
this.sources.set(source.name, source);
|
||||
|
||||
if (isParentProcess) {
|
||||
if (isParentProcess && sources.length > 0) {
|
||||
this._synchronizeSharedData();
|
||||
Services.locale.availableLocales = this.getAvailableLocales();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing source in the L10nRegistry
|
||||
* Updates existing sources in the L10nRegistry
|
||||
*
|
||||
* That will usually happen when a new version of a source becomes
|
||||
* available (for example, an updated version of a language pack).
|
||||
*
|
||||
* @param {FileSource} source
|
||||
* Notice: Each invocation of this method flushes any changes out to extant
|
||||
* content processes, which is expensive. Please coalesce multiple updates
|
||||
* into a single sources array and then call this method once.
|
||||
*
|
||||
* @param {Array<FileSource>} sources
|
||||
*/
|
||||
updateSource(source) {
|
||||
if (!this.hasSource(source.name)) {
|
||||
throw new Error(`Source with name "${source.name}" is not registered.`);
|
||||
updateSources(sources) {
|
||||
for (const source of sources) {
|
||||
if (!this.hasSource(source.name)) {
|
||||
throw new Error(`Source with name "${source.name}" is not registered.`);
|
||||
}
|
||||
this.sources.set(source.name, source);
|
||||
}
|
||||
this.sources.set(source.name, source);
|
||||
if (isParentProcess) {
|
||||
if (isParentProcess && sources.length > 0) {
|
||||
this._synchronizeSharedData();
|
||||
Services.locale.availableLocales = this.getAvailableLocales();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a source from the L10nRegistry.
|
||||
* Removes sources from the L10nRegistry.
|
||||
*
|
||||
* @param {String} sourceId
|
||||
* Notice: Each invocation of this method flushes any changes out to extant
|
||||
* content processes, which is expensive. Please coalesce multiple removals
|
||||
* into a single sourceNames array and then call this method once.
|
||||
*
|
||||
* @param {Array<String>} sourceNames
|
||||
*/
|
||||
removeSource(sourceName) {
|
||||
this.sources.delete(sourceName);
|
||||
if (isParentProcess) {
|
||||
removeSources(sourceNames) {
|
||||
for (const sourceName of sourceNames) {
|
||||
this.sources.delete(sourceName);
|
||||
}
|
||||
if (isParentProcess && sourceNames.length > 0) {
|
||||
this._synchronizeSharedData();
|
||||
Services.locale.availableLocales = this.getAvailableLocales();
|
||||
}
|
||||
@ -260,7 +278,11 @@ class L10nRegistryService {
|
||||
prePath: source.prePath,
|
||||
});
|
||||
}
|
||||
Services.ppmm.sharedData.set("L10nRegistry:Sources", sources);
|
||||
let sharedData = Services.ppmm.sharedData;
|
||||
sharedData.set("L10nRegistry:Sources", sources);
|
||||
// We must explicitly flush or else flushing won't happen until the main
|
||||
// thread goes idle.
|
||||
sharedData.flush();
|
||||
}
|
||||
|
||||
_setSourcesFromSharedData() {
|
||||
@ -269,17 +291,21 @@ class L10nRegistryService {
|
||||
console.warn(`[l10nregistry] Failed to fetch sources from shared data.`);
|
||||
return;
|
||||
}
|
||||
let registerSourcesList = [];
|
||||
for (let [name, data] of sources.entries()) {
|
||||
if (!this.hasSource(name)) {
|
||||
const source = new FileSource(name, data.locales, data.prePath);
|
||||
this.registerSource(source);
|
||||
registerSourcesList.push(source);
|
||||
}
|
||||
}
|
||||
this.registerSources(registerSourcesList);
|
||||
let removeSourcesList = [];
|
||||
for (let name of this.sources.keys()) {
|
||||
if (!sources.has(name)) {
|
||||
this.removeSource(name);
|
||||
removeSourcesList.push(name);
|
||||
}
|
||||
}
|
||||
this.removeSources(removeSourcesList);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user