diff options
author | vman <public@vaughnnugent.com> | 2022-11-30 14:59:09 -0500 |
---|---|---|
committer | vman <public@vaughnnugent.com> | 2022-11-30 14:59:09 -0500 |
commit | c9d9e6d23ad7b6fdf25f30de9b4a84be23885e16 (patch) | |
tree | 6f8336e55da2b06bfac2204510bf661dfa1a1476 /VNLib.Plugins.Extensions.Loading | |
parent | e8a846c83ca9922761db56373bc93fe4ea3f4021 (diff) |
Project cleanup + analyzer updates
Diffstat (limited to 'VNLib.Plugins.Extensions.Loading')
6 files changed, 66 insertions, 17 deletions
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 /// </summary> [AttributeUsage(AttributeTargets.Class)] - public class ConfigurationNameAttribute : Attribute + public sealed class ConfigurationNameAttribute : Attribute { /// <summary> /// /// </summary> - public readonly string ConfigVarName; + public string ConfigVarName { get; } /// <summary> /// Initializes a new <see cref="ConfigurationNameAttribute"/> @@ -167,7 +167,7 @@ namespace VNLib.Plugins.Extensions.Loading Type type = typeof(T); ConfigurationNameAttribute? configName = type.GetCustomAttribute<ConfigurationNameAttribute>(); //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 _); } /// <summary> 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 /// </summary> [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 /// </summary> [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<PluginBase, Lazy<PasswordHashing>> LazyPasswordTable = new(); - + /// <summary> /// Gets the plugins ambient <see cref="PasswordHashing"/> 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"); } } + + /// <summary> + /// Schedules an asynchronous callback function to run and its results will be observed + /// when the operation completes, or when the plugin is unloading + /// </summary> + /// <param name="plugin"></param> + /// <param name="asyncTask">The asynchronous operation to observe</param> + /// <param name="delayMs">An optional startup delay for the operation</param> + /// <returns>A task that completes when the deferred task completes </returns> + /// <exception cref="ObjectDisposedException"></exception> + public static async Task DeferTask(this PluginBase plugin, Func<Task> 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<object>? 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<Action<object>>(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 @@ <TargetFramework>net6.0</TargetFramework> <Copyright>Copyright © 2022 Vaughn Nugent</Copyright> <Authors>Vaughn Nugent</Authors> - <Version>1.0.0.1</Version> - <Platforms>AnyCPU;x64</Platforms> + <Version>1.0.1.1</Version> + <GenerateDocumentationFile>True</GenerateDocumentationFile> <Nullable>enable</Nullable> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> - <DocumentationFile></DocumentationFile> - </PropertyGroup> - - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <DocumentationFile></DocumentationFile> + <PropertyGroup> + <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> + <PackageProjectUrl>https://www.vaughnnugent.com/resources</PackageProjectUrl> + <AnalysisLevel>latest-all</AnalysisLevel> </PropertyGroup> <ItemGroup> |