From db835755e01b13dcb8d33a91f57ae8f20b931c57 Mon Sep 17 00:00:00 2001 From: Rory& Date: Sun, 9 Mar 2025 17:24:34 +0100 Subject: Well known resolver work, synapse admin work --- .../Extensions/NamedCaches/NamedCache.cs | 58 ++++++++++++++++------ 1 file changed, 44 insertions(+), 14 deletions(-) (limited to 'LibMatrix/Homeservers/Extensions') diff --git a/LibMatrix/Homeservers/Extensions/NamedCaches/NamedCache.cs b/LibMatrix/Homeservers/Extensions/NamedCaches/NamedCache.cs index 622eef6..9f11fa0 100644 --- a/LibMatrix/Homeservers/Extensions/NamedCaches/NamedCache.cs +++ b/LibMatrix/Homeservers/Extensions/NamedCaches/NamedCache.cs @@ -3,35 +3,65 @@ namespace LibMatrix.Homeservers.Extensions.NamedCaches; public class NamedCache(AuthenticatedHomeserverGeneric hs, string name) where T : class { private Dictionary? _cache = new(); private DateTime _expiry = DateTime.MinValue; - + private SemaphoreSlim _lock = new(1, 1); + + public TimeSpan ExpiryTime { get; set; } = TimeSpan.FromMinutes(5); + public DateTime GetCurrentExpiryTime() => _expiry; + + /// + /// Update the cached map with the latest data from the homeserver. + /// + /// The updated data public async Task> ReadCacheMapAsync() { - _cache = await hs.GetAccountDataOrNullAsync>(name); + _cache = await hs.GetAccountDataAsync>(name); return _cache ?? new(); } - - public async Task> ReadCacheMapCachedAsync() { + + public async Task> ReadCacheMapCachedAsync() { + await _lock.WaitAsync(); if (_expiry < DateTime.Now || _cache == null) { _cache = await ReadCacheMapAsync(); - _expiry = DateTime.Now.AddMinutes(5); + _expiry = DateTime.Now.Add(ExpiryTime); } + _lock.Release(); + return _cache; } - - public virtual async Task GetValueAsync(string key) { - return (await ReadCacheMapCachedAsync()).GetValueOrDefault(key); + + public virtual async Task GetValueAsync(string key, bool useCache = true) { + return (await (useCache ? ReadCacheMapCachedAsync() : ReadCacheMapAsync())).GetValueOrDefault(key); } - - public virtual async Task SetValueAsync(string key, T value) { - var cache = await ReadCacheMapCachedAsync(); + + public virtual async Task SetValueAsync(string key, T value, bool unsafeUseCache = false) { + if (!unsafeUseCache) + await _lock.WaitAsync(); + var cache = await (unsafeUseCache ? ReadCacheMapCachedAsync() : ReadCacheMapAsync()); cache[key] = value; await hs.SetAccountDataAsync(name, cache); + if (!unsafeUseCache) + _lock.Release(); + return value; } - - public virtual async Task GetOrSetValueAsync(string key, Func> value) { - return (await ReadCacheMapCachedAsync()).GetValueOrDefault(key) ?? await SetValueAsync(key, await value()); + + public virtual async Task RemoveValueAsync(string key, bool unsafeUseCache = false) { + if (!unsafeUseCache) + await _lock.WaitAsync(); + var cache = await (unsafeUseCache ? ReadCacheMapCachedAsync() : ReadCacheMapAsync()); + var removedValue = cache[key]; + cache.Remove(key); + await hs.SetAccountDataAsync(name, cache); + + if (!unsafeUseCache) + _lock.Release(); + + return removedValue; + } + + public virtual async Task GetOrSetValueAsync(string key, Func> value, bool unsafeUseCache = false) { + return (await (unsafeUseCache ? ReadCacheMapCachedAsync() : ReadCacheMapAsync())).GetValueOrDefault(key) ?? await SetValueAsync(key, await value()); } } \ No newline at end of file -- cgit 1.5.1