diff options
author | vnugent <public@vaughnnugent.com> | 2023-09-22 12:29:32 -0400 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2023-09-22 12:29:32 -0400 |
commit | 04c8fa8017a04da05cd8e1d104cfcd0a9aba17f5 (patch) | |
tree | 771243c218e880346fc7d826fa25ac2d639b01be /lib/Plugins.Essentials.ServiceStack | |
parent | 0b4e18b9a7d8e0aea23aef7efd3707674f223b2b (diff) |
Structure refactor & unused feature pruning, more http2 prep
Diffstat (limited to 'lib/Plugins.Essentials.ServiceStack')
4 files changed, 65 insertions, 19 deletions
diff --git a/lib/Plugins.Essentials.ServiceStack/src/HttpServiceStackBuilder.cs b/lib/Plugins.Essentials.ServiceStack/src/HttpServiceStackBuilder.cs index 5997cf9..95c6878 100644 --- a/lib/Plugins.Essentials.ServiceStack/src/HttpServiceStackBuilder.cs +++ b/lib/Plugins.Essentials.ServiceStack/src/HttpServiceStackBuilder.cs @@ -23,6 +23,7 @@ */ using System; +using System.Linq; using System.Collections.Generic; using VNLib.Net.Http; @@ -36,6 +37,7 @@ namespace VNLib.Plugins.Essentials.ServiceStack /// </summary> public sealed class HttpServiceStackBuilder { + /// <summary> /// Initializes a new <see cref="HttpServiceStack"/> that will /// generate servers to listen for services exposed by the @@ -54,7 +56,7 @@ namespace VNLib.Plugins.Essentials.ServiceStack /// </summary> /// <param name="hostBuilder">The callback method to build virtual hosts</param> /// <returns>The current instance for chaining</returns> - public HttpServiceStackBuilder WithDomainBuilder(Action<ICollection<IServiceHost>> hostBuilder) + public HttpServiceStackBuilder WithDomain(Action<ICollection<IServiceHost>> hostBuilder) { _hostBuilder = hostBuilder; return this; @@ -83,7 +85,29 @@ namespace VNLib.Plugins.Essentials.ServiceStack } /// <summary> - /// Builds the new <see cref="HttpServiceStack"/> from the configured callbacks, WITHOUT loading plugins + /// Configures the stack to use the built-in http server implementation + /// </summary> + /// <param name="transport">The transport builder callback function</param> + /// <param name="config">The http configuration structure used to initalize servers</param> + /// <returns>The current instance for chaining</returns> + public HttpServiceStackBuilder WithBuiltInHttp(Func<ServiceGroup, ITransportProvider> transport, HttpConfig config) + { + return WithHttp(sg => new HttpServer(config, transport(sg), sg.Hosts.Select(static p => p.Processor))); + } + + /// <summary> + /// Configures the stack to use the built-in http server implementation + /// </summary> + /// <param name="transport">The transport builder callback function</param> + /// <param name="configCallback">The http configuration builder callback method</param> + /// <returns>The current instance for chaining</returns> + public HttpServiceStackBuilder WithBuiltInHttp(Func<ServiceGroup, ITransportProvider> transport, Func<ServiceGroup, HttpConfig> configCallback) + { + return WithHttp(sg => new HttpServer(configCallback(sg), transport(sg), sg.Hosts.Select(static p => p.Processor))); + } + + /// <summary> + /// Builds the new <see cref="HttpServiceStack"/> from the configured callbacks /// </summary> /// <returns>The newly constructed <see cref="HttpServiceStack"/> that may be used to manage your http services</returns> /// <exception cref="ArgumentNullException"></exception> diff --git a/lib/Plugins.Essentials.ServiceStack/src/IServiceHost.cs b/lib/Plugins.Essentials.ServiceStack/src/IServiceHost.cs index 5d8fbe7..2517d66 100644 --- a/lib/Plugins.Essentials.ServiceStack/src/IServiceHost.cs +++ b/lib/Plugins.Essentials.ServiceStack/src/IServiceHost.cs @@ -40,7 +40,7 @@ namespace VNLib.Plugins.Essentials.ServiceStack IWebRoot Processor { get; } /// <summary> - /// The host's transport infomration + /// The host's transport information /// </summary> IHostTransportInfo TransportInfo { get; } diff --git a/lib/Plugins.Essentials.ServiceStack/src/ManagedPlugin.cs b/lib/Plugins.Essentials.ServiceStack/src/ManagedPlugin.cs index 0fe4c93..429a465 100644 --- a/lib/Plugins.Essentials.ServiceStack/src/ManagedPlugin.cs +++ b/lib/Plugins.Essentials.ServiceStack/src/ManagedPlugin.cs @@ -112,9 +112,6 @@ namespace VNLib.Plugins.Essentials.ServiceStack { //Dispose services _services?.Dispose(); - - //Dispose loader - Plugin.Dispose(); } diff --git a/lib/Plugins.Essentials.ServiceStack/src/PluginManager.cs b/lib/Plugins.Essentials.ServiceStack/src/PluginManager.cs index 208001a..eb26e92 100644 --- a/lib/Plugins.Essentials.ServiceStack/src/PluginManager.cs +++ b/lib/Plugins.Essentials.ServiceStack/src/PluginManager.cs @@ -29,7 +29,6 @@ using System.Linq; using System.Diagnostics; using System.Threading.Tasks; using System.Collections.Generic; -using System.Runtime.CompilerServices; using VNLib.Utils; using VNLib.Utils.Logging; @@ -45,7 +44,7 @@ namespace VNLib.Plugins.Essentials.ServiceStack /// </summary> internal sealed class PluginManager : VnDisposeable, IHttpPluginManager, IPluginEventListener { - private readonly ConditionalWeakTable<PluginController, ManagedPlugin> _managedPlugins; + private readonly Dictionary<PluginController, ManagedPlugin> _managedPlugins; private readonly ServiceDomain _dependents; private readonly IPluginStack _stack; @@ -71,7 +70,11 @@ namespace VNLib.Plugins.Essentials.ServiceStack { _ = _stack ?? throw new InvalidOperationException("Plugin stack has not been set."); - //Build the plugin stack + /* + * Since we own the plugin stack, it is safe to build it here. + * This method is not public and should not be called more than + * once. Otherwise it can cause issues with the plugin stack. + */ _stack.BuildStack(); //Register for plugin events @@ -83,15 +86,24 @@ namespace VNLib.Plugins.Essentials.ServiceStack //Add all wrappers to the managed plugins table Array.ForEach(wrapper, w => _managedPlugins.Add(w.Plugin.Controller, w)); - //Init remaining controllers single-threaded + //Init remaining controllers single-threaded because it may mutate the table _managedPlugins.Select(p => p.Value).TryForeach(w => InitializePlugin(w.Plugin, debugLog)); //Load stage, load all multithreaded - Parallel.ForEach(wrapper, wp => LoadPlugin(wp.Plugin, debugLog)); + Parallel.ForEach(_managedPlugins.Values, wp => LoadPlugin(wp.Plugin, debugLog)); debugLog.Information("Plugin loading completed"); } + /* + * Plugins are manually loaded by this manager instead of the stack shortcut extensions + * because I want to catch individual exceptions. + * + * I do not prefer this method as I would prefer loading is handled by the stack + * and the host not by this library. + * + * This will change in the future. + */ private void InitializePlugin(RuntimePluginLoader plugin, ILogProvider debugLog) { @@ -108,7 +120,7 @@ namespace VNLib.Plugins.Essentials.ServiceStack */ if (!plugin.Controller.Plugins.Any()) { - debugLog.Warn("No plugin instances were exposed via {ams} assembly. This may be due to an assebmly mismatch", fileName); + debugLog.Warn("No plugin instances were exposed via {asm} assembly. This may be due to an assebmly mismatch", fileName); } } catch (Exception ex) @@ -117,9 +129,6 @@ namespace VNLib.Plugins.Essentials.ServiceStack //Remove the plugin from the table _managedPlugins.Remove(plugin.Controller); - - //Dispose the plugin - plugin.Dispose(); } } @@ -191,12 +200,25 @@ namespace VNLib.Plugins.Essentials.ServiceStack //Dispose all managed plugins and clear the table _managedPlugins.TryForeach(p => p.Value.Dispose()); _managedPlugins.Clear(); + + //Dispose the plugin stack + _stack.Dispose(); } + /* + * When using a service stack an loading manually, plugins that have errors + * will not be captured by this instance. However when using the shortcut + * extensions, the events will be invoked regaldess if we loaded the plugin + * here. + */ + void IPluginEventListener.OnPluginLoaded(PluginController controller, object? state) { - //Handle service events - ManagedPlugin mp = _managedPlugins.GetValue(controller, (pc) => null!); + //Make sure the plugin is managed by this manager + if(!_managedPlugins.TryGetValue(controller, out ManagedPlugin? mp)) + { + return; + } //Run onload method before invoking other handlers mp.OnPluginLoaded(); @@ -210,8 +232,11 @@ namespace VNLib.Plugins.Essentials.ServiceStack void IPluginEventListener.OnPluginUnloaded(PluginController controller, object? state) { - //Handle service events - ManagedPlugin mp = _managedPlugins.GetValue(controller, (pc) => null!); + //Make sure the plugin is managed by this manager + if (!_managedPlugins.TryGetValue(controller, out ManagedPlugin? mp)) + { + return; + } //Run onload method before invoking other handlers mp.OnPluginUnloaded(); |