diff options
Diffstat (limited to 'VNLib.Plugins.Extensions.Loading/Events')
-rw-r--r-- | VNLib.Plugins.Extensions.Loading/Events/EventHandle.cs | 114 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Loading/Events/EventManagment.cs | 56 |
2 files changed, 52 insertions, 118 deletions
diff --git a/VNLib.Plugins.Extensions.Loading/Events/EventHandle.cs b/VNLib.Plugins.Extensions.Loading/Events/EventHandle.cs deleted file mode 100644 index e9f3ff0..0000000 --- a/VNLib.Plugins.Extensions.Loading/Events/EventHandle.cs +++ /dev/null @@ -1,114 +0,0 @@ -/* -* Copyright (c) 2022 Vaughn Nugent -* -* Library: VNLib -* Package: VNLib.Plugins.Extensions.Loading -* File: EventHandle.cs -* -* EventHandle.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 General Public License as published -* by the Free Software Foundation, either version 2 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 -* General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with VNLib.Plugins.Extensions.Loading. If not, see http://www.gnu.org/licenses/. -*/ - -using System; -using System.Threading; -using System.Threading.Tasks; - -using VNLib.Utils; -using VNLib.Utils.Extensions; -using VNLib.Utils.Logging; -using VNLib.Utils.Resources; - -namespace VNLib.Plugins.Extensions.Loading.Events -{ - /// <summary> - /// Represents a handle to a scheduled event interval that is managed by the plugin but may be cancled by disposing the instance - /// </summary> - public class EventHandle : VnDisposeable - { - private readonly PluginBase _pbase; - private readonly Timer _eventTimer; - private readonly TimeSpan _interval; - private readonly AsyncSchedulableCallback _callback; - - internal EventHandle(AsyncSchedulableCallback callback, TimeSpan interval, PluginBase pbase) - { - _pbase = pbase; - _interval = interval; - _callback = callback; - - //Init new timer - _eventTimer = new(OnTimerElapsed, this, interval, interval); - - //Register dispose to unload token - _ = pbase.UnloadToken.RegisterUnobserved(Dispose); - } - - private void OnTimerElapsed(object? state) - { - //Run on task scheuler - _ = Task.Run(RunInterval) - .ConfigureAwait(false); - } - - private async Task RunInterval() - { - try - { - await _callback(_pbase.Log, _pbase.UnloadToken); - } - catch (OperationCanceledException) - { - //unloaded - _pbase.Log.Verbose("Interval callback canceled due to plugin unload or other event cancellation"); - } - catch (Exception ex) - { - _pbase.Log.Error(ex, "Unhandled exception raised during timer callback"); - } - } - - /// <summary> - /// Invokes the event handler manually and observes the result. - /// This method writes execptions to the plugin's default log provider. - /// </summary> - /// <returns></returns> - /// <exception cref="ObjectDisposedException"></exception> - public Task ManualInvoke() - { - Check(); - return Task.Run(RunInterval); - } - - - /// <summary> - /// Pauses the event timer until the <see cref="OpenHandle"/> is released or disposed - /// then resumes to the inital interval period - /// </summary> - /// <returns>A <see cref="OpenHandle"/> that restores the timer to its initial state when disposed</returns> - /// <exception cref="ObjectDisposedException"></exception> - public OpenHandle Pause() - { - Check(); - return _eventTimer.Stop(_interval); - } - - ///<inheritdoc/> - protected override void Free() - { - _eventTimer.Dispose(); - } - } -} diff --git a/VNLib.Plugins.Extensions.Loading/Events/EventManagment.cs b/VNLib.Plugins.Extensions.Loading/Events/EventManagment.cs index 356cb8b..af55852 100644 --- a/VNLib.Plugins.Extensions.Loading/Events/EventManagment.cs +++ b/VNLib.Plugins.Extensions.Loading/Events/EventManagment.cs @@ -50,17 +50,65 @@ namespace VNLib.Plugins.Extensions.Loading.Events /// <param name="plugin"></param> /// <param name="asyncCallback">An asyncrhonous callback method.</param> /// <param name="interval">The event interval</param> + /// <param name="immediate">A value that indicates if the callback should be run as soon as possible</param> /// <returns>An <see cref="EventHandle"/> that can manage the interval state</returns> /// <exception cref="ObjectDisposedException"></exception> /// <remarks>If exceptions are raised during callback execution, they are written to the plugin's default log provider</remarks> - public static EventHandle ScheduleInterval(this PluginBase plugin, AsyncSchedulableCallback asyncCallback, TimeSpan interval) + public static void ScheduleInterval(this PluginBase plugin, AsyncSchedulableCallback asyncCallback, TimeSpan interval, bool immediate = false) { plugin.ThrowIfUnloaded(); plugin.Log.Verbose("Interval for {t} scheduled", interval); - //Load new event handler - return new(asyncCallback, interval, plugin); + + //Run interval on plugins bg scheduler + _ = plugin.DeferTask(() => RunIntervalOnPluginScheduler(plugin, asyncCallback, interval, immediate)); } + + private static async Task RunIntervalOnPluginScheduler(PluginBase plugin, AsyncSchedulableCallback callback, TimeSpan interval, bool immediate) + { + + static async Task RunCallbackAsync(PluginBase plugin, AsyncSchedulableCallback callback) + { + try + { + //invoke interval callback + await callback(plugin.Log, plugin.UnloadToken).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + //unloaded + plugin.Log.Verbose("Interval callback canceled due to plugin unload or other event cancellation"); + } + catch (Exception ex) + { + plugin.Log.Error(ex, "Unhandled exception raised during timer callback"); + } + } + + //Run callback immediatly if requested + if (immediate) + { + await RunCallbackAsync(plugin, callback); + } + + //Timer loop + while (true) + { + try + { + //await delay and wait for plugin cancellation + await Task.Delay(interval, plugin.UnloadToken); + } + catch (TaskCanceledException) + { + //Unload token canceled, exit loop + break; + } + + await RunCallbackAsync(plugin, callback); + } + } + /// <summary> /// Registers an <see cref="IIntervalScheduleable"/> type's event handler for /// raising timed interval events @@ -71,7 +119,7 @@ namespace VNLib.Plugins.Extensions.Loading.Events /// <returns>An <see cref="EventHandle"/> that can manage the interval state</returns> /// <exception cref="ObjectDisposedException"></exception> /// <remarks>If exceptions are raised during callback execution, they are written to the plugin's default log provider</remarks> - public static EventHandle ScheduleInterval(this PluginBase plugin, IIntervalScheduleable scheduleable, TimeSpan interval) => + public static void ScheduleInterval(this PluginBase plugin, IIntervalScheduleable scheduleable, TimeSpan interval) => ScheduleInterval(plugin, scheduleable.OnIntervalAsync, interval); } } |