aboutsummaryrefslogtreecommitdiff
path: root/lib/VNLib.Plugins.Extensions.Loading
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-01-27 21:13:17 -0500
committerLibravatar vnugent <public@vaughnnugent.com>2023-01-27 21:13:17 -0500
commit282aad617b9c39a6f14c1cf527f6dd4523d0c54b (patch)
treed2942722aad3c2fb087f8639a5fc667f6767456c /lib/VNLib.Plugins.Extensions.Loading
parent94ee5cc9090b40fe042187362acd18c0995866f4 (diff)
Object cache overhaul and logger updates
Diffstat (limited to 'lib/VNLib.Plugins.Extensions.Loading')
-rw-r--r--lib/VNLib.Plugins.Extensions.Loading/src/Events/EventManagment.cs2
-rw-r--r--lib/VNLib.Plugins.Extensions.Loading/src/IAsyncBackgroundWork.cs46
-rw-r--r--lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs22
-rw-r--r--lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs40
-rw-r--r--lib/VNLib.Plugins.Extensions.Loading/src/VNLib.Plugins.Extensions.Loading.csproj2
-rw-r--r--lib/VNLib.Plugins.Extensions.Loading/src/VaultSecrets.cs2
6 files changed, 94 insertions, 20 deletions
diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/Events/EventManagment.cs b/lib/VNLib.Plugins.Extensions.Loading/src/Events/EventManagment.cs
index fde67f7..bde6986 100644
--- a/lib/VNLib.Plugins.Extensions.Loading/src/Events/EventManagment.cs
+++ b/lib/VNLib.Plugins.Extensions.Loading/src/Events/EventManagment.cs
@@ -60,7 +60,7 @@ namespace VNLib.Plugins.Extensions.Loading.Events
plugin.Log.Verbose("Interval for {t} scheduled", interval);
//Run interval on plugins bg scheduler
- _ = plugin.DeferTask(() => RunIntervalOnPluginScheduler(plugin, asyncCallback, interval, immediate));
+ _ = plugin.ObserveTask(() => RunIntervalOnPluginScheduler(plugin, asyncCallback, interval, immediate));
}
private static async Task RunIntervalOnPluginScheduler(PluginBase plugin, AsyncSchedulableCallback callback, TimeSpan interval, bool immediate)
diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/IAsyncBackgroundWork.cs b/lib/VNLib.Plugins.Extensions.Loading/src/IAsyncBackgroundWork.cs
new file mode 100644
index 0000000..9fb66a2
--- /dev/null
+++ b/lib/VNLib.Plugins.Extensions.Loading/src/IAsyncBackgroundWork.cs
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2022 Vaughn Nugent
+*
+* Library: VNLib
+* Package: VNLib.Plugins.Extensions.Loading
+* File: LoadingExtensions.cs
+*
+* LoadingExtensions.cs is part of VNLib.Plugins.Extensions.Loading which is part of the larger
+* VNLib collection of libraries and utilities.
+*
+* VNLib.Plugins.Extensions.Loading is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License as
+* published by the Free Software Foundation, either version 3 of the
+* License, or (at your option) any later version.
+*
+* VNLib.Plugins.Extensions.Loading is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+
+using System.Threading.Tasks;
+using VNLib.Utils.Logging;
+using System.Threading;
+
+namespace VNLib.Plugins.Extensions.Loading
+{
+ /// <summary>
+ /// Represents a low priority or long running work task to be done
+ /// and observed by a loaded plugin
+ /// </summary>
+ public interface IAsyncBackgroundWork
+ {
+ /// <summary>
+ /// Called when low priority work is ready to be run and its results
+ /// marshaled back to the plugin context
+ /// </summary>
+ /// <param name="pluginLog">The plugins default log provider</param>
+ /// <param name="exitToken">A token that signals when the plugin is unloading and work should be cancelled</param>
+ /// <returns>A task representing the low priority work to observed</returns>
+ Task DoWorkAsync(ILogProvider pluginLog, CancellationToken exitToken);
+ }
+}
diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs b/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs
index 25dc4ec..743566d 100644
--- a/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs
+++ b/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs
@@ -38,6 +38,7 @@ using VNLib.Plugins.Essentials.Accounts;
namespace VNLib.Plugins.Extensions.Loading
{
+
/// <summary>
/// Provides common loading (and unloading when required) extensions for plugins
/// </summary>
@@ -225,7 +226,7 @@ namespace VNLib.Plugins.Extensions.Loading
/// <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)
+ public static async Task ObserveTask(this PluginBase plugin, Func<Task> asyncTask, int delayMs = 0)
{
/*
* Motivation:
@@ -266,6 +267,20 @@ namespace VNLib.Plugins.Extensions.Loading
}
}
+
+ /// <summary>
+ /// Schedules work to begin after the specified delay to be observed by the plugin while
+ /// passing plugin specifie information. Exceptions are logged to the default plugin log
+ /// </summary>
+ /// <param name="plugin"></param>
+ /// <param name="work">The work to be observed</param>
+ /// <param name="delayMs">The time (in milliseconds) to delay dispatching the work item</param>
+ /// <returns>The task that represents the scheduled work</returns>
+ public static Task ObserveWork(this PluginBase plugin, IAsyncBackgroundWork work, int delayMs = 0)
+ {
+ return ObserveTask(plugin, () => work.DoWorkAsync(plugin.Log, plugin.UnloadToken), delayMs);
+ }
+
/// <summary>
/// Registers an event to occur when the plugin is unloaded on a background thread
/// and will cause the Plugin.Unload() method to block until the event completes
@@ -292,10 +307,9 @@ namespace VNLib.Plugins.Extensions.Loading
}
//Registaer the task to cause the plugin to wait
- return pbase.DeferTask(() => WaitForUnload(pbase, callback));
+ return pbase.ObserveTask(() => WaitForUnload(pbase, callback));
}
-
private sealed class PluginLocalCache
{
private readonly PluginBase _plugin;
@@ -356,7 +370,7 @@ namespace VNLib.Plugins.Extensions.Loading
public void LoadSecret(PluginBase pbase)
{
- _ = pbase.DeferTask(() => LoadSecretInternal(pbase));
+ _ = pbase.ObserveTask(() => LoadSecretInternal(pbase));
}
private async Task LoadSecretInternal(PluginBase pbase)
diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs b/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs
index f27b3b3..c1c6bb6 100644
--- a/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs
+++ b/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.Runtime.CompilerServices;
using VNLib.Plugins.Extensions.Loading.Events;
+using System.Net;
namespace VNLib.Plugins.Extensions.Loading.Routing
{
@@ -50,42 +51,53 @@ namespace VNLib.Plugins.Extensions.Loading.Routing
public static T Route<T>(this PluginBase plugin, string? pluginConfigPathName) where T : IEndpoint
{
Type endpointType = typeof(T);
+
+ T endpoint;
+
//If the config attribute is not set, then ignore the config variables
if (string.IsNullOrWhiteSpace(pluginConfigPathName))
{
ConstructorInfo? constructor = endpointType.GetConstructor(new Type[] { typeof(PluginBase) });
+
_ = constructor ?? throw new EntryPointNotFoundException($"No constructor found for {endpointType.Name}");
+
//Create the new endpoint and pass the plugin instance
- T endpoint = (T)constructor.Invoke(new object[] { plugin });
+ endpoint = (T)constructor.Invoke(new object[] { plugin });
+
//Register event handlers for the endpoint
ScheduleIntervals(plugin, endpoint, endpointType, null);
- //Route the endpoint
- plugin.Route(endpoint);
-
- //Store ref to plugin for endpoint
- _pluginRefs.Add(endpoint, plugin);
-
- return endpoint;
}
else
{
ConstructorInfo? constructor = endpointType.GetConstructor(new Type[] { typeof(PluginBase), typeof(IReadOnlyDictionary<string, JsonElement>) });
+
//Make sure the constructor exists
_ = constructor ?? throw new EntryPointNotFoundException($"No constructor found for {endpointType.Name}");
+
//Get config variables for the endpoint
IReadOnlyDictionary<string, JsonElement> conf = plugin.GetConfig(pluginConfigPathName);
+
//Create the new endpoint and pass the plugin instance along with the configuration object
- T endpoint = (T)constructor.Invoke(new object[] { plugin, conf });
+ endpoint = (T)constructor.Invoke(new object[] { plugin, conf });
+
//Register event handlers for the endpoint
ScheduleIntervals(plugin, endpoint, endpointType, conf);
- //Route the endpoint
- plugin.Route(endpoint);
+ }
- //Store ref to plugin for endpoint
- _pluginRefs.Add(endpoint, plugin);
+ //Route the endpoint
+ plugin.Route(endpoint);
- return endpoint;
+ //Store ref to plugin for endpoint
+ _pluginRefs.Add(endpoint, plugin);
+
+ //See if the endpoint is disposable
+ if (endpoint is IDisposable dis)
+ {
+ //Register dispose for unload
+ _ = plugin.RegisterForUnload(dis.Dispose);
}
+
+ return endpoint;
}
/// <summary>
diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/VNLib.Plugins.Extensions.Loading.csproj b/lib/VNLib.Plugins.Extensions.Loading/src/VNLib.Plugins.Extensions.Loading.csproj
index c31ae1c..a660a7e 100644
--- a/lib/VNLib.Plugins.Extensions.Loading/src/VNLib.Plugins.Extensions.Loading.csproj
+++ b/lib/VNLib.Plugins.Extensions.Loading/src/VNLib.Plugins.Extensions.Loading.csproj
@@ -28,7 +28,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0" />
- <PackageReference Include="VaultSharp" Version="1.7.1" />
+ <PackageReference Include="VaultSharp" Version="1.12.2.1" />
</ItemGroup>
<ItemGroup>
diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/VaultSecrets.cs b/lib/VNLib.Plugins.Extensions.Loading/src/VaultSecrets.cs
index d3bdf42..da6650a 100644
--- a/lib/VNLib.Plugins.Extensions.Loading/src/VaultSecrets.cs
+++ b/lib/VNLib.Plugins.Extensions.Loading/src/VaultSecrets.cs
@@ -78,6 +78,7 @@ namespace VNLib.Plugins.Extensions.Loading
/// <exception cref="ObjectDisposedException"></exception>
public static Task<SecretResult?> TryGetSecretAsync(this PluginBase plugin, string secretName)
{
+ plugin.ThrowIfUnloaded();
//Get the secret from the config file raw
string? rawSecret = TryGetSecretInternal(plugin, secretName);
if (rawSecret == null)
@@ -159,6 +160,7 @@ namespace VNLib.Plugins.Extensions.Loading
/// <exception cref="ObjectDisposedException"></exception>
public static Task<X509Certificate?> TryGetCertificateAsync(this PluginBase plugin, string secretName)
{
+ plugin.ThrowIfUnloaded();
//Get the secret from the config file raw
string? rawSecret = TryGetSecretInternal(plugin, secretName);
if (rawSecret == null)