From b03905afda2dde2be88013c3b026dcb8c0dd5c84 Mon Sep 17 00:00:00 2001 From: Noi Date: Thu, 25 Aug 2022 18:40:06 -0700 Subject: [PATCH] Add SharedEventService Forgot to put in b4db1fc --- .../SharedEventService/SharedEventService.cs | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 Services/SharedEventService/SharedEventService.cs diff --git a/Services/SharedEventService/SharedEventService.cs b/Services/SharedEventService/SharedEventService.cs new file mode 100644 index 0000000..728cf5e --- /dev/null +++ b/Services/SharedEventService/SharedEventService.cs @@ -0,0 +1,48 @@ +using System.Threading.Channels; + +namespace RegexBot.Services.SharedEventService; +/// +/// Implements a queue which any service or module may send objects into, +/// which are then sent to subscribing services and/or modules. Allows for simple, +/// basic sharing of information between separate parts of the program. +/// +class SharedEventService : Service { + private readonly Channel _items; + //private readonly Task _itemPropagationWorker; + + internal SharedEventService(RegexbotClient bot) : base(bot) { + _items = Channel.CreateUnbounded(); + _ = Task.Factory.StartNew(ItemPropagator, CancellationToken.None, + TaskCreationOptions.LongRunning, TaskScheduler.Default); + } + + // Hooked (lock this on self) + internal event RegexbotClient.IncomingSharedEventHandler? Subscribers; + + internal async Task PushSharedEventAsync(ISharedEvent ev) { + await _items.Writer.WriteAsync(ev); + } + + private async Task ItemPropagator() { + while (true) { + var ev = await _items.Reader.ReadAsync(); + + Delegate[]? subscribed; + lock (this) { + subscribed = Subscribers?.GetInvocationList(); + if (subscribed == null || subscribed.Length == 0) return; + } + + foreach (var handler in subscribed) { + // Fire and forget! + _ = Task.Run(async () => { + try { + await (Task)handler.DynamicInvoke(ev)!; + } catch (Exception ex) { + Log("Unhandled exception in shared event handler:" + ex.ToString()); + } + }); + } + } + } +}