extensionSystem: Update immediately after major upgrades
Currently we periodically check for updated extensions, prepare an update and perform it at the next login. This is largely due to the fact that once an extension has been loaded, its code is cached and reloading it would only make it *appear* as updated, while in reality still running the old code. Of course this only applies *once* we have loaded extensions. Before that, it's possible to download and install updates, and only then initialize extensions with their latest version. The trade-off is that network requests, data download and extraction may introduce a significant delay before extensions are enabled. Most extensions modify the UI one way or another, so that delay would likely be noticeable by the user. Assuming that users are usually happy enough with the current extension version, that trade-off doesn't seem worthwhile. However there is an exception: After a major version update, extensions are likely disabled as out-of-date, or at least more likely to break (when the version check is disabled). In that case delaying extension initialization to download and install updates looks like the better trade-off, so do that. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2951>
This commit is contained in:
parent
1cc5e770ea
commit
ba46a1cf54
@ -27,6 +27,8 @@ export class ExtensionManager extends Signals.EventEmitter {
|
||||
|
||||
this._initializationPromise = null;
|
||||
this._updateNotified = false;
|
||||
this._updateInProgress = false;
|
||||
this._updatedUUIDS = [];
|
||||
|
||||
this._extensions = new Map();
|
||||
this._unloadedExtensions = new Map();
|
||||
@ -316,6 +318,11 @@ export class ExtensionManager extends Signals.EventEmitter {
|
||||
}
|
||||
|
||||
notifyExtensionUpdate(uuid) {
|
||||
if (this._updateInProgress) {
|
||||
this._updatedUUIDS.push(uuid);
|
||||
return;
|
||||
}
|
||||
|
||||
let extension = this.lookup(uuid);
|
||||
if (!extension)
|
||||
return;
|
||||
@ -646,6 +653,30 @@ export class ExtensionManager extends Signals.EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
async _handleMajorUpdate() {
|
||||
const [majorVersion] = Config.PACKAGE_VERSION.split('.');
|
||||
const path = `${global.userdatadir}/update-check-${majorVersion}`;
|
||||
const file = Gio.File.new_for_path(path);
|
||||
|
||||
try {
|
||||
if (!await file.touch_async())
|
||||
return;
|
||||
} catch (e) {
|
||||
logError(e);
|
||||
}
|
||||
|
||||
this._updateInProgress = true;
|
||||
|
||||
await ExtensionDownloader.checkForUpdates();
|
||||
this._installExtensionUpdates();
|
||||
|
||||
this._updatedUUIDS.map(uuid => this.lookup(uuid)).forEach(
|
||||
ext => this.reloadExtension(ext));
|
||||
this._updatedUUIDS = [];
|
||||
|
||||
this._updateInProgress = false;
|
||||
}
|
||||
|
||||
_installExtensionUpdates() {
|
||||
if (!this.updatesSupported)
|
||||
return;
|
||||
@ -719,6 +750,10 @@ export class ExtensionManager extends Signals.EventEmitter {
|
||||
return extension;
|
||||
}).filter(extension => extension !== null);
|
||||
|
||||
// after updating to a new major version,
|
||||
// update extensions before loading them
|
||||
await this._handleMajorUpdate();
|
||||
|
||||
for (const extension of extensionObjects) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await this.loadExtension(extension);
|
||||
|
Loading…
Reference in New Issue
Block a user