diff options
author | vnugent <public@vaughnnugent.com> | 2024-01-06 18:02:33 -0500 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2024-01-06 18:02:33 -0500 |
commit | 107f9774df2ad484f3edc5f401c738f647f00f01 (patch) | |
tree | 8eae2347c0a424d274d2f798b625be50c05a562b /lib/VNLib.Plugins.Extensions.Loading/src/RoutingExtensions.cs | |
parent | 778ece00a279b176636f9a4314cd20bf7867793c (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.cs | 139 |
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 { |