mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2026-02-07 07:14:25 +01:00
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:
committed by
Nicolas Dorier
parent
a571f77a40
commit
3e9bee2d44
7
BTCPayServer/Events/SettingsChanged.cs
Normal file
7
BTCPayServer/Events/SettingsChanged.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace BTCPayServer.Events
|
||||
{
|
||||
public class SettingsChanged<T>
|
||||
{
|
||||
public T Settings { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user