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/LoadingExtensions.cs | |
parent | e8a846c83ca9922761db56373bc93fe4ea3f4021 (diff) |
Project cleanup + analyzer updates
Diffstat (limited to 'VNLib.Plugins.Extensions.Loading/LoadingExtensions.cs')
-rw-r--r-- | VNLib.Plugins.Extensions.Loading/LoadingExtensions.cs | 57 |
1 files changed, 54 insertions, 3 deletions
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); + } + } } } |