pm: don't install updates twice, don't globally lock the plugin list while updates are installing

This commit is contained in:
goat 2024-07-07 12:21:48 +02:00
parent c028fecf62
commit df51fc17e6
4 changed files with 41 additions and 12 deletions

View file

@ -119,6 +119,16 @@ internal class AutoUpdateManager : IServiceType
/// </summary>
public bool IsAutoUpdateComplete { get; private set; }
/// <summary>
/// Gets the time of the next scheduled update check.
/// </summary>
public DateTime? NextUpdateCheckTime => this.nextUpdateCheckTime;
/// <summary>
/// Gets the time the auto-update was unblocked.
/// </summary>
public DateTime? UnblockedSince => this.unblockedSince;
private static UpdateListingRestriction DecideUpdateListingRestriction(AutoUpdateBehavior behavior)
{
return behavior switch

View file

@ -995,20 +995,16 @@ internal class PluginManager : IInternalDisposableService
var totalPlugins = toUpdate.Count;
var processedPlugins = 0;
// Prevent collection was modified errors
lock (this.pluginListLock)
foreach (var plugin in toUpdate)
{
foreach (var plugin in toUpdate)
{
// Can't update that!
if (plugin.InstalledPlugin.IsDev)
continue;
// Can't update that!
if (plugin.InstalledPlugin.IsDev)
continue;
if (plugin.InstalledPlugin.Manifest.ScheduledForDeletion)
continue;
if (plugin.InstalledPlugin.Manifest.ScheduledForDeletion)
continue;
updateTasks.Add(UpdateSinglePluginWithProgressAsync(plugin));
}
updateTasks.Add(UpdateSinglePluginWithProgressAsync(plugin));
}
var updatedList = await Task.WhenAll(updateTasks);
@ -1065,6 +1061,18 @@ internal class PluginManager : IInternalDisposableService
Status = PluginUpdateStatus.StatusKind.Success,
HasChangelog = !metadata.UpdateManifest.Changelog.IsNullOrWhitespace(),
};
// Check if this plugin is already up to date (=> AvailablePluginUpdate was stale)
lock (this.installedPluginsList)
{
var matchedPlugin = this.installedPluginsList.FirstOrDefault(x => x.EffectiveWorkingPluginId == workingPluginId);
if (matchedPlugin?.EffectiveVersion == metadata.EffectiveVersion)
{
Log.Information("Plugin {Name} is already up to date", plugin.Manifest.Name);
updateStatus.Status = PluginUpdateStatus.StatusKind.AlreadyUpToDate;
return updateStatus;
}
}
if (!dryRun)
{
@ -1457,7 +1465,7 @@ internal class PluginManager : IInternalDisposableService
// ignored, since the plugin may be loaded already
}
Log.Debug($"Extracting to {outputDir}");
Log.Debug("Extracting to {OutputDir}", outputDir);
using (var archive = new ZipArchive(zipStream))
{

View file

@ -34,4 +34,10 @@ internal record AvailablePluginUpdate
/// Gets a value indicating whether the update should use the testing URL.
/// </summary>
public bool UseTesting { get; init; }
/// <summary>
/// Gets the effective version to use for the update.
/// </summary>
public Version EffectiveVersion => (this.UseTesting ? this.UpdateManifest.TestingAssemblyVersion : this.UpdateManifest.AssemblyVersion)
?? throw new Exception("Update manifest does not contain a valid version.");
}

View file

@ -32,6 +32,11 @@ internal class PluginUpdateStatus
/// </summary>
FailedLoad,
/// <summary>
/// The updated plugin is already up to date.
/// </summary>
AlreadyUpToDate,
/// <summary>
/// The update succeeded.
/// </summary>