From a6f52ce4a03f954273f7b2e2930db1d59e005fc6 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 25 May 2021 23:15:40 +0200 Subject: [PATCH] Core - Refactored (unused) queued actions system --- .../Interfaces/IPluginManagementService.cs | 13 ++-- .../Services/PluginManagementService.cs | 63 +++++++++++++------ .../Entities/General/QueuedActionEntity.cs | 19 ++++++ .../Entities/Plugins/PluginSettingEntity.cs | 17 ----- .../Interfaces/IPluginRepository.cs | 8 +-- .../Interfaces/IQueuedActionRepository.cs | 13 ++++ .../Repositories/ModuleRepository.cs | 3 +- .../Repositories/PluginRepository.cs | 20 ------ .../Repositories/QueuedActionRepository.cs | 46 ++++++++++++++ 9 files changed, 134 insertions(+), 68 deletions(-) create mode 100644 src/Artemis.Storage/Entities/General/QueuedActionEntity.cs create mode 100644 src/Artemis.Storage/Repositories/Interfaces/IQueuedActionRepository.cs create mode 100644 src/Artemis.Storage/Repositories/QueuedActionRepository.cs diff --git a/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs b/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs index d0719bd38..ddd61d6cd 100644 --- a/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs +++ b/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs @@ -135,11 +135,16 @@ namespace Artemis.Core.Services DeviceProvider GetDeviceProviderByDevice(IRGBDevice device); /// - /// Queues an action for the provided plugin for the next time Artemis starts, before plugins are loaded + /// Queues the provided plugin to be deleted the next time Artemis starts, before plugins are loaded /// - /// The plugin to queue the action for - /// The action to take - void QueuePluginAction(Plugin plugin, PluginManagementAction pluginAction); + /// The plugin to delete + void QueuePluginDeletion(Plugin plugin); + + /// + /// Removes the provided plugin for the deletion queue it was added to via + /// + /// The plugin to dequeue + void DequeuePluginDeletion(Plugin plugin); /// /// Occurs when built-in plugins are being loaded diff --git a/src/Artemis.Core/Services/PluginManagementService.cs b/src/Artemis.Core/Services/PluginManagementService.cs index 5655b8112..c9c698be7 100644 --- a/src/Artemis.Core/Services/PluginManagementService.cs +++ b/src/Artemis.Core/Services/PluginManagementService.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Reflection; using Artemis.Core.DeviceProviders; using Artemis.Core.Ninject; +using Artemis.Storage.Entities.General; using Artemis.Storage.Entities.Plugins; using Artemis.Storage.Repositories.Interfaces; using McMaster.NETCore.Plugins; @@ -26,17 +27,19 @@ namespace Artemis.Core.Services private readonly IKernel _kernel; private readonly ILogger _logger; private readonly IPluginRepository _pluginRepository; + private readonly IQueuedActionRepository _queuedActionRepository; private readonly List _plugins; private bool _isElevated; - public PluginManagementService(IKernel kernel, ILogger logger, IPluginRepository pluginRepository) + public PluginManagementService(IKernel kernel, ILogger logger, IPluginRepository pluginRepository, IQueuedActionRepository queuedActionRepository) { _kernel = kernel; _logger = logger; _pluginRepository = pluginRepository; + _queuedActionRepository = queuedActionRepository; _plugins = new List(); - ProcessQueuedActions(); + ProcessPluginDeletionQueue(); } private void CopyBuiltInPlugin(ZipArchive zipArchive, string targetDirectory) @@ -664,27 +667,51 @@ namespace Artemis.Core.Services #region Queued actions - public void QueuePluginAction(Plugin plugin, PluginManagementAction pluginAction) + public void QueuePluginDeletion(Plugin plugin) { - List existing = _pluginRepository.GetQueuedActions(plugin.Guid); - if (existing.Any(e => pluginAction == PluginManagementAction.Delete && e is PluginQueuedDeleteEntity)) - return; - - if (pluginAction == PluginManagementAction.Delete) - _pluginRepository.AddQueuedAction(new PluginQueuedDeleteEntity {PluginGuid = plugin.Guid, Directory = plugin.Directory.FullName}); + _queuedActionRepository.Add(new QueuedActionEntity + { + Type = "DeletePlugin", + CreatedAt = DateTimeOffset.Now, + Parameters = new Dictionary() + { + {"pluginGuid", plugin.Guid.ToString()}, + {"plugin", plugin.ToString()}, + {"directory", plugin.Directory.FullName} + } + }); } - private void ProcessQueuedActions() + public void DequeuePluginDeletion(Plugin plugin) { - foreach (PluginQueuedActionEntity pluginQueuedActionEntity in _pluginRepository.GetQueuedActions()) - { - if (pluginQueuedActionEntity is PluginQueuedDeleteEntity deleteAction) - { - if (Directory.Exists(deleteAction.Directory)) - Directory.Delete(deleteAction.Directory, true); - } + QueuedActionEntity? queuedActionEntity = _queuedActionRepository.GetByType("DeletePlugin").FirstOrDefault(q => q.Parameters["pluginGuid"].Equals(plugin.Guid.ToString())); + if (queuedActionEntity != null) + _queuedActionRepository.Remove(queuedActionEntity); + } - _pluginRepository.RemoveQueuedAction(pluginQueuedActionEntity); + private void ProcessPluginDeletionQueue() + { + foreach (QueuedActionEntity queuedActionEntity in _queuedActionRepository.GetByType("DeletePlugin")) + { + string? directory = queuedActionEntity.Parameters["directory"].ToString(); + try + { + if (Directory.Exists(directory)) + { + _logger.Information("Queued plugin deletion - deleting folder - {plugin}", queuedActionEntity.Parameters["plugin"]); + Directory.Delete(directory!, true); + } + else + { + _logger.Information("Queued plugin deletion - folder already deleted - {plugin}", queuedActionEntity.Parameters["plugin"]); + } + + _queuedActionRepository.Remove(queuedActionEntity); + } + catch (Exception e) + { + _logger.Warning(e, "Queued plugin deletion failed - {plugin}", queuedActionEntity.Parameters["plugin"]); + } } } diff --git a/src/Artemis.Storage/Entities/General/QueuedActionEntity.cs b/src/Artemis.Storage/Entities/General/QueuedActionEntity.cs new file mode 100644 index 000000000..62eeee417 --- /dev/null +++ b/src/Artemis.Storage/Entities/General/QueuedActionEntity.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace Artemis.Storage.Entities.General +{ + public class QueuedActionEntity + { + public QueuedActionEntity() + { + Parameters = new Dictionary(); + } + + public Guid Id { get; set; } + public string Type { get; set; } + public DateTimeOffset CreatedAt { get; set; } + + public Dictionary Parameters { get; set; } + } +} \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Plugins/PluginSettingEntity.cs b/src/Artemis.Storage/Entities/Plugins/PluginSettingEntity.cs index 08a17f922..ae4827426 100644 --- a/src/Artemis.Storage/Entities/Plugins/PluginSettingEntity.cs +++ b/src/Artemis.Storage/Entities/Plugins/PluginSettingEntity.cs @@ -13,21 +13,4 @@ namespace Artemis.Storage.Entities.Plugins public string Name { get; set; } public string Value { get; set; } } - - /// - /// Represents a queued action for a plugin - /// - public abstract class PluginQueuedActionEntity - { - public Guid Id { get; set; } - public Guid PluginGuid { get; set; } - } - - /// - /// Represents a queued delete action for a plugin - /// - public class PluginQueuedDeleteEntity : PluginQueuedActionEntity - { - public string Directory { get; set; } - } } \ No newline at end of file diff --git a/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs index 602eb2572..8b559b255 100644 --- a/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs +++ b/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using Artemis.Storage.Entities.Plugins; namespace Artemis.Storage.Repositories.Interfaces @@ -9,16 +8,11 @@ namespace Artemis.Storage.Repositories.Interfaces void AddPlugin(PluginEntity pluginEntity); PluginEntity GetPluginByGuid(Guid pluginGuid); void SavePlugin(PluginEntity pluginEntity); - + void AddSetting(PluginSettingEntity pluginSettingEntity); PluginSettingEntity GetSettingByGuid(Guid pluginGuid); PluginSettingEntity GetSettingByNameAndGuid(string name, Guid pluginGuid); void SaveSetting(PluginSettingEntity pluginSettingEntity); void RemoveSettings(Guid pluginGuid); - - void AddQueuedAction(PluginQueuedActionEntity pluginQueuedActionEntity); - List GetQueuedActions(); - List GetQueuedActions(Guid pluginGuid); - void RemoveQueuedAction(PluginQueuedActionEntity pluginQueuedActionEntity); } } \ No newline at end of file diff --git a/src/Artemis.Storage/Repositories/Interfaces/IQueuedActionRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IQueuedActionRepository.cs new file mode 100644 index 000000000..20d7db070 --- /dev/null +++ b/src/Artemis.Storage/Repositories/Interfaces/IQueuedActionRepository.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Artemis.Storage.Entities.General; + +namespace Artemis.Storage.Repositories.Interfaces +{ + public interface IQueuedActionRepository : IRepository + { + void Add(QueuedActionEntity queuedActionEntity); + void Remove(QueuedActionEntity queuedActionEntity); + List GetAll(); + List GetByType(string type); + } +} \ No newline at end of file diff --git a/src/Artemis.Storage/Repositories/ModuleRepository.cs b/src/Artemis.Storage/Repositories/ModuleRepository.cs index 9d733507c..aae79d974 100644 --- a/src/Artemis.Storage/Repositories/ModuleRepository.cs +++ b/src/Artemis.Storage/Repositories/ModuleRepository.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using Artemis.Storage.Entities.Module; using Artemis.Storage.Repositories.Interfaces; using LiteDB; diff --git a/src/Artemis.Storage/Repositories/PluginRepository.cs b/src/Artemis.Storage/Repositories/PluginRepository.cs index db67f0c91..9a2ec11e3 100644 --- a/src/Artemis.Storage/Repositories/PluginRepository.cs +++ b/src/Artemis.Storage/Repositories/PluginRepository.cs @@ -15,7 +15,6 @@ namespace Artemis.Storage.Repositories _repository = repository; _repository.Database.GetCollection().EnsureIndex(s => new {s.Name, s.PluginGuid}, true); - _repository.Database.GetCollection().EnsureIndex(s => s.PluginGuid); } public void AddPlugin(PluginEntity pluginEntity) @@ -59,24 +58,5 @@ namespace Artemis.Storage.Repositories { _repository.DeleteMany(s => s.PluginGuid == pluginGuid); } - - public List GetQueuedActions() - { - return _repository.Query().ToList(); - } - - public List GetQueuedActions(Guid pluginGuid) - { - return _repository.Query().Where(q => q.PluginGuid == pluginGuid).ToList(); - } - - public void AddQueuedAction(PluginQueuedActionEntity pluginQueuedActionEntity) - { - _repository.Upsert(pluginQueuedActionEntity); - } - public void RemoveQueuedAction(PluginQueuedActionEntity pluginQueuedActionEntity) - { - _repository.Delete(pluginQueuedActionEntity.Id); - } } } \ No newline at end of file diff --git a/src/Artemis.Storage/Repositories/QueuedActionRepository.cs b/src/Artemis.Storage/Repositories/QueuedActionRepository.cs new file mode 100644 index 000000000..1376149d5 --- /dev/null +++ b/src/Artemis.Storage/Repositories/QueuedActionRepository.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using Artemis.Storage.Entities.General; +using Artemis.Storage.Repositories.Interfaces; +using LiteDB; + +namespace Artemis.Storage.Repositories +{ + public class QueuedActionRepository : IQueuedActionRepository + { + private readonly LiteRepository _repository; + + public QueuedActionRepository(LiteRepository repository) + { + _repository = repository; + _repository.Database.GetCollection().EnsureIndex(s => s.Type); + } + + #region Implementation of IQueuedActionRepository + + /// + public void Add(QueuedActionEntity queuedActionEntity) + { + _repository.Insert(queuedActionEntity); + } + + /// + public void Remove(QueuedActionEntity queuedActionEntity) + { + _repository.Delete(queuedActionEntity.Id); + } + + /// + public List GetAll() + { + return _repository.Query().ToList(); + } + + /// + public List GetByType(string type) + { + return _repository.Query().Where(q => q.Type == type).ToList(); + } + + #endregion + } +} \ No newline at end of file