From 3e9bee2d449349cd79af5b76e969e927b7e6a680 Mon Sep 17 00:00:00 2001 From: Andrew Camilleri Date: Thu, 22 Aug 2019 13:44:06 +0200 Subject: [PATCH] simplify settings changed listening (#976) * simplify settings changed listening Might as well use the Event aggregator to listen in on changes instead of the current complicated magic in the settings repo. This also reduces db calls( it sends the new settings through the event instead of fetching them again) * add settings extension * switch to old style but using event aggregator --- BTCPayServer/Events/SettingsChanged.cs | 7 +++ BTCPayServer/Services/SettingsRepository.cs | 67 +++++---------------- 2 files changed, 22 insertions(+), 52 deletions(-) create mode 100644 BTCPayServer/Events/SettingsChanged.cs diff --git a/BTCPayServer/Events/SettingsChanged.cs b/BTCPayServer/Events/SettingsChanged.cs new file mode 100644 index 000000000..b90d13cb3 --- /dev/null +++ b/BTCPayServer/Events/SettingsChanged.cs @@ -0,0 +1,7 @@ +namespace BTCPayServer.Events +{ + public class SettingsChanged + { + public T Settings { get; set; } + } +} \ No newline at end of file diff --git a/BTCPayServer/Services/SettingsRepository.cs b/BTCPayServer/Services/SettingsRepository.cs index 4c9b32e58..fdd76de52 100644 --- a/BTCPayServer/Services/SettingsRepository.cs +++ b/BTCPayServer/Services/SettingsRepository.cs @@ -1,23 +1,22 @@ using BTCPayServer.Data; -using System; -using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Identity.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore; -using BTCPayServer.Models; -using Microsoft.EntityFrameworkCore.Infrastructure.Internal; -using Newtonsoft.Json; using System.Threading; +using System.Threading.Tasks; +using BTCPayServer.Events; +using Microsoft.EntityFrameworkCore; +using Newtonsoft.Json; namespace BTCPayServer.Services { public class SettingsRepository { private ApplicationDbContextFactory _ContextFactory; - public SettingsRepository(ApplicationDbContextFactory contextFactory) + private readonly EventAggregator _EventAggregator; + + public SettingsRepository(ApplicationDbContextFactory contextFactory, EventAggregator eventAggregator) { _ContextFactory = contextFactory; + _EventAggregator = eventAggregator; } public async Task GetSettingAsync() @@ -52,22 +51,11 @@ namespace BTCPayServer.Services await ctx.SaveChangesAsync(); } } + _EventAggregator.Publish(new SettingsChanged() + { + Settings = obj + }); - IReadOnlyCollection> value; - lock (_Subscriptions) - { - if(_Subscriptions.TryGetValue(typeof(T), out value)) - { - _Subscriptions.Remove(typeof(T)); - } - } - if(value != null) - { - foreach(var v in value) - { - v.TrySetResult(true); - } - } } private T Deserialize(string value) @@ -79,35 +67,10 @@ namespace BTCPayServer.Services { return JsonConvert.SerializeObject(obj); } - - MultiValueDictionary> _Subscriptions = new MultiValueDictionary>(); - public async Task WaitSettingsChanged(CancellationToken cancellation) + + public async Task WaitSettingsChanged(CancellationToken cancellationToken = default) { - var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - using (cancellation.Register(() => - { - try - { - tcs.TrySetCanceled(); - } - catch { } - })) - { - lock (_Subscriptions) - { - _Subscriptions.Add(typeof(T), tcs); - } -#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed - tcs.Task.ContinueWith(_ => - { - lock (_Subscriptions) - { - _Subscriptions.Remove(typeof(T), tcs); - } - }, TaskScheduler.Default); -#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed - await tcs.Task; - } + return (await _EventAggregator.WaitNext>(cancellationToken)).Settings; } } }