aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2024-01-06 18:02:33 -0500
committerLibravatar vnugent <public@vaughnnugent.com>2024-01-06 18:02:33 -0500
commit107f9774df2ad484f3edc5f401c738f647f00f01 (patch)
tree8eae2347c0a424d274d2f798b625be50c05a562b
parent778ece00a279b176636f9a4314cd20bf7867793c (diff)
proj updates, interval deprecation & convert routes to services
-rw-r--r--lib/VNLib.Plugins.Extensions.Loading/src/Events/ConfigurableAsyncIntervalAttribute.cs1
-rw-r--r--lib/VNLib.Plugins.Extensions.Loading/src/Events/EventManagment.cs5
-rw-r--r--lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs6
-rw-r--r--lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs139
4 files changed, 12 insertions, 139 deletions
diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/Events/ConfigurableAsyncIntervalAttribute.cs b/lib/VNLib.Plugins.Extensions.Loading/src/Events/ConfigurableAsyncIntervalAttribute.cs
index 171a9ae..be8c16b 100644
--- a/lib/VNLib.Plugins.Extensions.Loading/src/Events/ConfigurableAsyncIntervalAttribute.cs
+++ b/lib/VNLib.Plugins.Extensions.Loading/src/Events/ConfigurableAsyncIntervalAttribute.cs
@@ -30,6 +30,7 @@ namespace VNLib.Plugins.Extensions.Loading.Events
/// When added to a method schedules it as a callback on a specified interval when
/// the plugin is loaded, and stops when unloaded
/// </summary>
+ [Obsolete("Depricated in favor of more verbose IIntervaleSchedulable apis")]
[AttributeUsage(AttributeTargets.Method)]
public sealed class ConfigurableAsyncIntervalAttribute : Attribute
{
diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/Events/EventManagment.cs b/lib/VNLib.Plugins.Extensions.Loading/src/Events/EventManagment.cs
index 40a52fc..8b2ab40 100644
--- a/lib/VNLib.Plugins.Extensions.Loading/src/Events/EventManagment.cs
+++ b/lib/VNLib.Plugins.Extensions.Loading/src/Events/EventManagment.cs
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2023 Vaughn Nugent
+* Copyright (c) 2024 Vaughn Nugent
*
* Library: VNLib
* Package: VNLib.Plugins.Extensions.Loading
@@ -43,7 +43,8 @@ namespace VNLib.Plugins.Extensions.Loading.Events
/// Provides event schedueling extensions for plugins
/// </summary>
public static class EventManagment
- {
+ {
+
/// <summary>
/// Schedules an asynchronous event interval for the current plugin, that is active until canceled or until the plugin unloads
/// </summary>
diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs b/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs
index 979ade2..470d954 100644
--- a/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs
+++ b/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs
@@ -663,7 +663,7 @@ namespace VNLib.Plugins.Extensions.Loading
}
//Get the constructor for required or available config
- constructor = serviceType.GetConstructor(new Type[] { typeof(PluginBase), typeof(IConfigScope) });
+ constructor = serviceType.GetConstructor([typeof(PluginBase), typeof(IConfigScope)]);
//Make sure the constructor exists
_ = constructor ?? throw new MissingMemberException($"No constructor found for {serviceType.Name}");
@@ -671,13 +671,13 @@ namespace VNLib.Plugins.Extensions.Loading
//Call constructore
service = constructor.Invoke(new object[2] { plugin, config });
}
- else if((constructor = serviceType.GetConstructor(new Type[] { typeof(PluginBase) })) != null)
+ else if((constructor = serviceType.GetConstructor([typeof(PluginBase)])) != null)
{
//Call constructor
service = constructor.Invoke(new object[1] { plugin });
}
//try to get empty constructor
- else if ((constructor = serviceType.GetConstructor(Array.Empty<Type>())) != null)
+ else if ((constructor = serviceType.GetConstructor([])) != null)
{
//Invoked empty constructor
service = constructor.Invoke(null);
diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs b/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs
index c0f39d7..a1817a8 100644
--- a/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs
+++ b/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs
@@ -23,13 +23,11 @@
*/
using System;
-using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using VNLib.Plugins.Essentials.Runtime;
-using VNLib.Plugins.Extensions.Loading.Events;
namespace VNLib.Plugins.Extensions.Loading.Routing
{
@@ -47,74 +45,11 @@ namespace VNLib.Plugins.Extensions.Loading.Routing
/// </summary>
/// <typeparam name="T">The <see cref="IEndpoint"/> type</typeparam>
/// <param name="plugin"></param>
- /// <param name="configRequired">If true, requires the configuration exist in the config file</param>
- /// <param name="pluginConfigPathName">The path to the plugin sepcific configuration property</param>
/// <exception cref="TargetInvocationException"></exception>
- public static T Route<T>(this PluginBase plugin, string? pluginConfigPathName, bool configRequired = true) where T : IEndpoint
+ public static T Route<T>(this PluginBase plugin) where T : IEndpoint
{
- Type endpointType = typeof(T);
-
- T endpoint;
- try
- {
- //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 t(PluginBase p) found for {endpointType.Name}");
-
- //Create the new endpoint and pass the plugin instance
- endpoint = (T)constructor.Invoke(new object[] { plugin });
-
- //Register event handlers for the endpoint
- ScheduleIntervals(plugin, endpoint, endpointType, null);
- }
- else
- {
- //Try to get config but allow null if not required
- IConfigScope? config = plugin.TryGetConfig(pluginConfigPathName);
-
- if (configRequired && config == null)
- {
- ConfigurationExtensions.ThrowConfigNotFoundForType(endpointType);
- return default;
- }
-
- //Choose constructor based on config
- if (config != null)
- {
- ConstructorInfo? constructor = endpointType.GetConstructor(new Type[] { typeof(PluginBase), typeof(IConfigScope) });
-
- //Make sure the constructor exists
- _ = constructor ?? throw new EntryPointNotFoundException($"No constructor t(PluginBase p, IConfigScope cs) found for {endpointType.Name}");
-
- //Create the new endpoint and pass the plugin instance along with the configuration object
- endpoint = (T)constructor.Invoke(new object[] { plugin, config });
-
- //Register event handlers for the endpoint
- ScheduleIntervals(plugin, endpoint, endpointType, config);
- }
- else
- {
- //Config does not exist, so use the default constructor
- ConstructorInfo? constructor = endpointType.GetConstructor(new Type[] { typeof(PluginBase) });
-
- _ = constructor ?? throw new EntryPointNotFoundException($"No constructor t(PluginBase p) found for {endpointType.Name}");
-
- //Create the new endpoint and pass the plugin instance
- endpoint = (T)constructor.Invoke(new object[] { plugin });
-
- //Register event handlers for the endpoint
- ScheduleIntervals(plugin, endpoint, endpointType, null);
- }
- }
- }
- catch(TargetInvocationException te)
- {
- LoadingExtensions.FindAndThrowInnerException(te);
- throw;
- }
+ //Create the endpoint service, then route it
+ T endpoint = plugin.CreateService<T>();
//Route the endpoint
plugin.Route(endpoint);
@@ -122,32 +57,10 @@ namespace VNLib.Plugins.Extensions.Loading.Routing
//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>
- /// Constructs and routes the specific endpoint type for the current plugin
- /// </summary>
- /// <typeparam name="T">The <see cref="IEndpoint"/> type</typeparam>
- /// <param name="plugin"></param>
- /// <exception cref="TargetInvocationException"></exception>
- public static T Route<T>(this PluginBase plugin) where T : IEndpoint
- {
- Type endpointType = typeof(T);
- //Get config name attribute
- ConfigurationNameAttribute? configAttr = endpointType.GetCustomAttribute<ConfigurationNameAttribute>();
- //Route using attribute
- return plugin.Route<T>(configAttr?.ConfigVarName, configAttr?.Required == true);
- }
-
- /// <summary>
/// Routes a single endpoint for the current plugin and exports the collection to the
/// service pool
/// </summary>
@@ -183,50 +96,8 @@ namespace VNLib.Plugins.Extensions.Loading.Routing
{
_ = _pluginRefs.TryGetValue(ep, out PluginBase? pBase);
return pBase ?? throw new InvalidOperationException("Endpoint was not dynamically routed");
- }
-
- private static void ScheduleIntervals<T>(PluginBase plugin, T endpointInstance, Type epType, IConfigScope? endpointLocalConfig) where T : IEndpoint
- {
- //Get all methods that have the configurable async interval attribute specified
- IEnumerable<Tuple<ConfigurableAsyncIntervalAttribute, AsyncSchedulableCallback>> confIntervals = epType.GetMethods()
- .Where(m => m.GetCustomAttribute<ConfigurableAsyncIntervalAttribute>() != null)
- .Select(m => new Tuple<ConfigurableAsyncIntervalAttribute, AsyncSchedulableCallback>
- (m.GetCustomAttribute<ConfigurableAsyncIntervalAttribute>()!, m.CreateDelegate<AsyncSchedulableCallback>(endpointInstance)));
-
- //If the endpoint has a local config, then use it to find the interval
- if (endpointLocalConfig != null)
- {
-
- //Schedule event handlers on the current plugin
- foreach (Tuple<ConfigurableAsyncIntervalAttribute, AsyncSchedulableCallback> interval in confIntervals)
- {
- int value = endpointLocalConfig[interval.Item1.IntervalPropertyName].GetInt32();
- //Get the timeout from its resolution variable
- TimeSpan timeout = interval.Item1.Resolution switch
- {
- IntervalResultionType.Seconds => TimeSpan.FromSeconds(value),
- IntervalResultionType.Minutes => TimeSpan.FromMinutes(value),
- IntervalResultionType.Hours => TimeSpan.FromHours(value),
- _ => TimeSpan.FromMilliseconds(value),
- };
- //Schedule
- plugin.ScheduleInterval(interval.Item2, timeout);
- }
- }
-
- //Get all methods that have the async interval attribute specified
- IEnumerable<Tuple<AsyncIntervalAttribute, AsyncSchedulableCallback>> intervals = epType.GetMethods()
- .Where(m => m.GetCustomAttribute<AsyncIntervalAttribute>() != null)
- .Select(m => new Tuple<AsyncIntervalAttribute, AsyncSchedulableCallback>(
- m.GetCustomAttribute<AsyncIntervalAttribute>()!, m.CreateDelegate<AsyncSchedulableCallback>(endpointInstance))
- );
-
- //Schedule event handlers on the current plugin
- foreach (Tuple<AsyncIntervalAttribute, AsyncSchedulableCallback> interval in intervals)
- {
- plugin.ScheduleInterval(interval.Item2, interval.Item1.Interval);
- }
- }
+ }
+
private sealed class EndpointCollection : IVirtualEndpointDefinition
{