From c9d9e6d23ad7b6fdf25f30de9b4a84be23885e16 Mon Sep 17 00:00:00 2001 From: vman Date: Wed, 30 Nov 2022 14:59:09 -0500 Subject: Project cleanup + analyzer updates --- .../ConfigurationExtensions.cs | 6 +-- .../Events/AsyncIntervalAttribute.cs | 2 +- .../Events/ConfigurableAsyncIntervalAttribute.cs | 2 +- .../LoadingExtensions.cs | 57 ++++++++++++++++++++-- VNLib.Plugins.Extensions.Loading/UserLoading.cs | 2 +- .../VNLib.Plugins.Extensions.Loading.csproj | 14 +++--- 6 files changed, 66 insertions(+), 17 deletions(-) (limited to 'VNLib.Plugins.Extensions.Loading') diff --git a/VNLib.Plugins.Extensions.Loading/ConfigurationExtensions.cs b/VNLib.Plugins.Extensions.Loading/ConfigurationExtensions.cs index 0e6ff57..62b898c 100644 --- a/VNLib.Plugins.Extensions.Loading/ConfigurationExtensions.cs +++ b/VNLib.Plugins.Extensions.Loading/ConfigurationExtensions.cs @@ -37,12 +37,12 @@ namespace VNLib.Plugins.Extensions.Loading /// containing data specific to the type /// [AttributeUsage(AttributeTargets.Class)] - public class ConfigurationNameAttribute : Attribute + public sealed class ConfigurationNameAttribute : Attribute { /// /// /// - public readonly string ConfigVarName; + public string ConfigVarName { get; } /// /// Initializes a new @@ -167,7 +167,7 @@ namespace VNLib.Plugins.Extensions.Loading Type type = typeof(T); ConfigurationNameAttribute? configName = type.GetCustomAttribute(); //See if the plugin contains a configuration varables - return configName != null ? plugin.PluginConfig.TryGetProperty(configName.ConfigVarName, out _) : false; + return configName != null && plugin.PluginConfig.TryGetProperty(configName.ConfigVarName, out _); } /// diff --git a/VNLib.Plugins.Extensions.Loading/Events/AsyncIntervalAttribute.cs b/VNLib.Plugins.Extensions.Loading/Events/AsyncIntervalAttribute.cs index 0540ffa..85b0b6d 100644 --- a/VNLib.Plugins.Extensions.Loading/Events/AsyncIntervalAttribute.cs +++ b/VNLib.Plugins.Extensions.Loading/Events/AsyncIntervalAttribute.cs @@ -31,7 +31,7 @@ namespace VNLib.Plugins.Extensions.Loading.Events /// the plugin is loaded, and stops when unloaded /// [AttributeUsage(AttributeTargets.Method)] - public class AsyncIntervalAttribute : Attribute + public sealed class AsyncIntervalAttribute : Attribute { internal readonly TimeSpan Interval; diff --git a/VNLib.Plugins.Extensions.Loading/Events/ConfigurableAsyncIntervalAttribute.cs b/VNLib.Plugins.Extensions.Loading/Events/ConfigurableAsyncIntervalAttribute.cs index d141eba..12c5ec4 100644 --- a/VNLib.Plugins.Extensions.Loading/Events/ConfigurableAsyncIntervalAttribute.cs +++ b/VNLib.Plugins.Extensions.Loading/Events/ConfigurableAsyncIntervalAttribute.cs @@ -31,7 +31,7 @@ namespace VNLib.Plugins.Extensions.Loading.Events /// the plugin is loaded, and stops when unloaded /// [AttributeUsage(AttributeTargets.Method)] - public class ConfigurableAsyncIntervalAttribute : Attribute + public sealed class ConfigurableAsyncIntervalAttribute : Attribute { internal readonly string IntervalPropertyName; internal readonly IntervalResultionType Resolution; diff --git a/VNLib.Plugins.Extensions.Loading/LoadingExtensions.cs b/VNLib.Plugins.Extensions.Loading/LoadingExtensions.cs index 411b9b4..bfe0de1 100644 --- a/VNLib.Plugins.Extensions.Loading/LoadingExtensions.cs +++ b/VNLib.Plugins.Extensions.Loading/LoadingExtensions.cs @@ -26,11 +26,13 @@ using System; using System.IO; using System.Linq; using System.Text.Json; +using System.Threading.Tasks; using System.Collections.Generic; using System.Security.Cryptography; using System.Runtime.CompilerServices; using VNLib.Utils; +using VNLib.Utils.Logging; using VNLib.Utils.Extensions; using VNLib.Plugins.Essentials.Accounts; @@ -44,10 +46,9 @@ namespace VNLib.Plugins.Extensions.Loading public const string DEBUG_CONFIG_KEY = "debug"; public const string SECRETS_CONFIG_KEY = "secrets"; public const string PASSWORD_HASHING_KEY = "passwords"; - - + private static readonly ConditionalWeakTable> LazyPasswordTable = new(); - + /// /// Gets the plugins ambient if loaded, or loads it if required. This class will @@ -176,5 +177,55 @@ namespace VNLib.Plugins.Extensions.Loading throw new ObjectDisposedException("The plugin has been unloaded"); } } + + /// + /// Schedules an asynchronous callback function to run and its results will be observed + /// when the operation completes, or when the plugin is unloading + /// + /// + /// The asynchronous operation to observe + /// An optional startup delay for the operation + /// A task that completes when the deferred task completes + /// + public static async Task DeferTask(this PluginBase plugin, Func asyncTask, int delayMs = 0) + { + /* + * Motivation: + * Sometimes during plugin loading, a plugin may want to asynchronously load + * data, where the results are not required to be observed during loading, but + * should not be pending after the plugin is unloaded, as the assembly may be + * unloaded and referrences collected by the GC. + * + * So we can use the plugin's unload cancellation token to observe the results + * of a pending async operation + */ + + //Test status + plugin.ThrowIfUnloaded(); + + //Optional delay + await Task.Delay(delayMs); + + //Run on ts + Task deferred = Task.Run(asyncTask); + + //Add task to deferred list + plugin.DeferredTasks.Add(deferred); + try + { + //Await the task results + await deferred; + } + catch(Exception ex) + { + //Log errors + plugin.Log.Error(ex, "Error occured while observing deferred task"); + } + finally + { + //Remove task when complete + plugin.DeferredTasks.Remove(deferred); + } + } } } diff --git a/VNLib.Plugins.Extensions.Loading/UserLoading.cs b/VNLib.Plugins.Extensions.Loading/UserLoading.cs index b67af0d..3457dc3 100644 --- a/VNLib.Plugins.Extensions.Loading/UserLoading.cs +++ b/VNLib.Plugins.Extensions.Loading/UserLoading.cs @@ -81,7 +81,7 @@ namespace VNLib.Plugins.Extensions.Loading.Users //Get the onplugin load method Action? onLoadMethod = runtimeType.GetMethods() - .Where(static p => p.IsPublic && !p.IsAbstract && ONLOAD_METHOD_NAME.Equals(p.Name)) + .Where(static p => p.IsPublic && !p.IsAbstract && ONLOAD_METHOD_NAME.Equals(p.Name, StringComparison.Ordinal)) .Select(p => p.CreateDelegate>(loader.Resource)) .FirstOrDefault(); diff --git a/VNLib.Plugins.Extensions.Loading/VNLib.Plugins.Extensions.Loading.csproj b/VNLib.Plugins.Extensions.Loading/VNLib.Plugins.Extensions.Loading.csproj index 7a25ef1..43eefc2 100644 --- a/VNLib.Plugins.Extensions.Loading/VNLib.Plugins.Extensions.Loading.csproj +++ b/VNLib.Plugins.Extensions.Loading/VNLib.Plugins.Extensions.Loading.csproj @@ -4,18 +4,16 @@ net6.0 Copyright © 2022 Vaughn Nugent Vaughn Nugent - 1.0.0.1 - AnyCPU;x64 + 1.0.1.1 + True enable - - - - - - + + true + https://www.vaughnnugent.com/resources + latest-all -- cgit