aboutsummaryrefslogtreecommitdiff
path: root/lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs
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 /lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs
parent778ece00a279b176636f9a4314cd20bf7867793c (diff)
proj updates, interval deprecation & convert routes to services
Diffstat (limited to 'lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs')
-rw-r--r--lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs139
1 files changed, 5 insertions, 134 deletions
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
{