// WingsEmu // // Developed by NosWings Team using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Foundatio.Caching; namespace PhoenixLib.DAL.Redis { public sealed class RedisGenericKeyValueAsyncStorage : IKeyValueAsyncStorage where TKey : notnull { private readonly ICacheClient _cacheClient; private readonly string _dataPrefix; private readonly string _keySetKey; public RedisGenericKeyValueAsyncStorage(ICacheClient multiplexer) : this(typeof(TObject).Name.ToLower(), multiplexer) { } private RedisGenericKeyValueAsyncStorage(string basePrefix, ICacheClient multiplexer) { _dataPrefix = "data:" + basePrefix + ':'; _keySetKey = "keys:" + basePrefix; _cacheClient = multiplexer; } private Task>> KeySet => _cacheClient.GetListAsync(_keySetKey); public async Task> GetAllAsync() { return (await _cacheClient.GetAllAsync(await GetAllKeysAsync().ConfigureAwait(false)).ConfigureAwait(false)).Select(s => s.Value.Value); } public async Task ClearAllAsync() { CacheValue> keys = await KeySet; await _cacheClient.ListRemoveAsync(_keySetKey, keys); await _cacheClient.RemoveAllAsync(keys.Value); } public async Task GetByIdAsync(TKey id) => (await _cacheClient.GetAsync(ToKey(id)).ConfigureAwait(false)).Value; public async Task> GetByIdsAsync(IEnumerable ids) { return (await _cacheClient.GetAllAsync(ids.Select(ToKey))).Select(s => s.Value.Value); } public async Task RegisterAsync(TKey id, TObject obj, TimeSpan? lifeTime = null) { await RegisterKeyAsync(new[] { id }, lifeTime).ConfigureAwait(false); await _cacheClient.SetAsync(ToKey(id), obj, lifeTime).ConfigureAwait(false); } public async Task RegisterAsync(IEnumerable<(TKey, TObject)> objs, TimeSpan? lifeTime = null) { await RegisterKeyAsync(objs.Select(s => s.Item1), lifeTime).ConfigureAwait(false); await _cacheClient.SetAllAsync(objs.ToDictionary(s => ToKey(s.Item1), o => o), lifeTime).ConfigureAwait(false); } public async Task RemoveAsync(TKey id) { await RemoveKeyAsync(new[] { id }).ConfigureAwait(false); await _cacheClient.RemoveAsync(ToKey(id)).ConfigureAwait(false); return default; } public async Task> RemoveAsync(IEnumerable ids) { await RemoveKeyAsync(ids); await _cacheClient.RemoveAllAsync(ids.Select(ToKey)); return null; } private async Task> GetAllKeysAsync() => (await KeySet).Value; private Task RegisterKeyAsync(IEnumerable keys, TimeSpan? lifeTime) => _cacheClient.ListAddAsync(_keySetKey, keys.Select(ToKey), lifeTime); private Task RemoveKeyAsync(IEnumerable keys) => _cacheClient.ListRemoveAsync(_keySetKey, keys.Select(ToKey)); private string ToKey(TKey id) => _dataPrefix + id; } }