about summary refs log tree commit diff
path: root/LibMatrix/Homeservers/Extensions
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2025-03-09 17:24:34 +0100
committerRory& <root@rory.gay>2025-03-09 17:24:34 +0100
commitdb835755e01b13dcb8d33a91f57ae8f20b931c57 (patch)
tree9a7bb90b919bef042b4bfc064f603e760a472cc9 /LibMatrix/Homeservers/Extensions
parentWell known resolver rewrite work (diff)
downloadLibMatrix-db835755e01b13dcb8d33a91f57ae8f20b931c57.tar.xz
Well known resolver work, synapse admin work
Diffstat (limited to 'LibMatrix/Homeservers/Extensions')
-rw-r--r--LibMatrix/Homeservers/Extensions/NamedCaches/NamedCache.cs58
1 files changed, 44 insertions, 14 deletions
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<T>(AuthenticatedHomeserverGeneric hs, string name) where T : class { private Dictionary<string, T>? _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; + + /// <summary> + /// Update the cached map with the latest data from the homeserver. + /// </summary> + /// <returns>The updated data</returns> public async Task<Dictionary<string, T>> ReadCacheMapAsync() { - _cache = await hs.GetAccountDataOrNullAsync<Dictionary<string, T>>(name); + _cache = await hs.GetAccountDataAsync<Dictionary<string, T>>(name); return _cache ?? new(); } - - public async Task<Dictionary<string,T>> ReadCacheMapCachedAsync() { + + public async Task<Dictionary<string, T>> 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<T?> GetValueAsync(string key) { - return (await ReadCacheMapCachedAsync()).GetValueOrDefault(key); + + public virtual async Task<T?> GetValueAsync(string key, bool useCache = true) { + return (await (useCache ? ReadCacheMapCachedAsync() : ReadCacheMapAsync())).GetValueOrDefault(key); } - - public virtual async Task<T> SetValueAsync(string key, T value) { - var cache = await ReadCacheMapCachedAsync(); + + public virtual async Task<T> 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<T> GetOrSetValueAsync(string key, Func<Task<T>> value) { - return (await ReadCacheMapCachedAsync()).GetValueOrDefault(key) ?? await SetValueAsync(key, await value()); + + public virtual async Task<T> 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<T> GetOrSetValueAsync(string key, Func<Task<T>> value, bool unsafeUseCache = false) { + return (await (unsafeUseCache ? ReadCacheMapCachedAsync() : ReadCacheMapAsync())).GetValueOrDefault(key) ?? await SetValueAsync(key, await value()); } } \ No newline at end of file