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
This commit is contained in:
Andrew Camilleri
2019-08-22 13:44:06 +02:00
committed by Nicolas Dorier
parent a571f77a40
commit 3e9bee2d44
2 changed files with 22 additions and 52 deletions

View File

@@ -0,0 +1,7 @@
namespace BTCPayServer.Events
{
public class SettingsChanged<T>
{
public T Settings { get; set; }
}
}

View File

@@ -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<T> GetSettingAsync<T>()
@@ -52,22 +51,11 @@ namespace BTCPayServer.Services
await ctx.SaveChangesAsync();
}
}
_EventAggregator.Publish(new SettingsChanged<T>()
{
Settings = obj
});
IReadOnlyCollection<TaskCompletionSource<bool>> 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<T>(string value)
@@ -79,35 +67,10 @@ namespace BTCPayServer.Services
{
return JsonConvert.SerializeObject(obj);
}
MultiValueDictionary<Type, TaskCompletionSource<bool>> _Subscriptions = new MultiValueDictionary<Type, TaskCompletionSource<bool>>();
public async Task WaitSettingsChanged<T>(CancellationToken cancellation)
public async Task<T> WaitSettingsChanged<T>(CancellationToken cancellationToken = default)
{
var tcs = new TaskCompletionSource<bool>(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<SettingsChanged<T>>(cancellationToken)).Settings;
}
}
}