diff --git a/src/Artemis.Core/Plugins/PluginFeature.cs b/src/Artemis.Core/Plugins/PluginFeature.cs
index ef3917ba0..149d42632 100644
--- a/src/Artemis.Core/Plugins/PluginFeature.cs
+++ b/src/Artemis.Core/Plugins/PluginFeature.cs
@@ -12,7 +12,7 @@ namespace Artemis.Core
{
private bool _isEnabled;
-
+
///
/// Gets the plugin feature info related to this feature
///
@@ -37,6 +37,8 @@ namespace Artemis.Core
internal set => SetAndNotify(ref _isEnabled, value);
}
+ internal int AutoEnableAttempts { get; set; }
+
///
/// Gets the identifier of this plugin feature
///
@@ -137,6 +139,9 @@ namespace Artemis.Core
try
{
+ if (isAutoEnable)
+ AutoEnableAttempts++;
+
if (isAutoEnable && GetLockFileCreated())
{
// Don't wrap existing lock exceptions, simply rethrow them
@@ -157,6 +162,7 @@ namespace Artemis.Core
throw new ArtemisPluginException(Plugin, "Plugin load timeout");
Info.LoadException = null;
+ AutoEnableAttempts = 0;
OnEnabled();
}
// If enable failed, put it back in a disabled state
diff --git a/src/Artemis.Core/Services/PluginManagementService.cs b/src/Artemis.Core/Services/PluginManagementService.cs
index de01c754f..5e4841829 100644
--- a/src/Artemis.Core/Services/PluginManagementService.cs
+++ b/src/Artemis.Core/Services/PluginManagementService.cs
@@ -5,6 +5,7 @@ using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
+using System.Threading.Tasks;
using Artemis.Core.DeviceProviders;
using Artemis.Core.Ninject;
using Artemis.Storage.Entities.General;
@@ -90,7 +91,7 @@ namespace Artemis.Core.Services
using StreamReader reader = new(metaDataFileEntry.Open());
PluginInfo builtInPluginInfo = CoreJson.DeserializeObject(reader.ReadToEnd())!;
string preferred = builtInPluginInfo.PreferredPluginDirectory;
-
+
// Find the matching plugin in the plugin folder
DirectoryInfo? match = pluginDirectory.EnumerateDirectories().FirstOrDefault(d => d.Name == preferred);
if (match == null)
@@ -610,13 +611,38 @@ namespace Artemis.Core.Services
}
catch (Exception e)
{
- _logger.Warning(
- new ArtemisPluginException(pluginFeature.Plugin, $"Exception during SetEnabled(true) on {pluginFeature}", e),
- "Failed to enable plugin"
- );
+ if (isAutoEnable)
+ {
+ // Schedule a retry based on the amount of attempts
+ if (pluginFeature.AutoEnableAttempts < 4)
+ {
+ TimeSpan retryDelay = TimeSpan.FromSeconds(pluginFeature.AutoEnableAttempts * 10);
+ _logger.Warning(
+ e,
+ "Plugin feature '{feature} - {plugin}' failed to enable during attempt ({attempt}/3), scheduling a retry in {retryDelay}.",
+ pluginFeature,
+ pluginFeature.Plugin,
+ pluginFeature.AutoEnableAttempts,
+ retryDelay
+ );
- if (!isAutoEnable)
+ Task.Run(async () =>
+ {
+ await Task.Delay(retryDelay);
+ if (!pluginFeature.IsEnabled)
+ EnablePluginFeature(pluginFeature, saveState, true);
+ });
+ }
+ else
+ {
+ _logger.Warning(e, "Plugin feature '{feature} - {plugin}' failed to enable after 3 attempts, giving up.", pluginFeature, pluginFeature.Plugin);
+ }
+ }
+ else
+ {
+ _logger.Warning(e, "Plugin feature '{feature} - {plugin}' failed to enable.", pluginFeature, pluginFeature.Plugin);
throw;
+ }
}
finally
{