diff options
Diffstat (limited to 'lib/VNLib.Plugins.Extensions.VNCache')
9 files changed, 349 insertions, 43 deletions
diff --git a/lib/VNLib.Plugins.Extensions.VNCache/src/BucketLocalManagerFactory.cs b/lib/VNLib.Plugins.Extensions.VNCache/src/BucketLocalManagerFactory.cs new file mode 100644 index 0000000..cea06a3 --- /dev/null +++ b/lib/VNLib.Plugins.Extensions.VNCache/src/BucketLocalManagerFactory.cs @@ -0,0 +1,154 @@ +/* +* Copyright (c) 2023 Vaughn Nugent +* +* Library: VNLib +* Package: ObjectCacheServer +* File: BucketLocalManagerFactory.cs +* +* BucketLocalManagerFactory.cs is part of ObjectCacheServer which is part of the larger +* VNLib collection of libraries and utilities. +* +* ObjectCacheServer is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* ObjectCacheServer is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +*/ + +using System; +using System.Buffers; +using System.Text.Json; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +using VNLib.Plugins; +using VNLib.Utils; +using VNLib.Utils.Memory; +using VNLib.Utils.Extensions; +using VNLib.Plugins.Extensions.Loading; + +namespace VNLib.Data.Caching.ObjectCache.Server +{ + [ConfigurationName("memory_manager", Required = false)] + internal sealed class BucketLocalManagerFactory : VnDisposeable, ICacheMemoryManagerFactory + { + private readonly LinkedList<BucketLocalManager> _managers = new (); + private readonly bool _zeroAll; + + ///<inheritdoc/> + public ICacheEntryMemoryManager CreateForBucket(uint bucketId) + { + //Init a new heap for a individual bucket + IUnmangedHeap localHeap = MemoryUtil.InitializeNewHeapForProcess(); + + BucketLocalManager manager = new (localHeap, bucketId, _zeroAll); + _managers.AddLast(manager); + + return manager; + } + + /// <summary> + /// Creates a new <see cref="BucketLocalManagerFactory"/> with the specified zero all flag + /// that is not managed by a plugin instance + /// </summary> + /// <param name="zeroAll">Forces all allocations to be zeroed before being returned to callers</param> + /// <returns></returns> + public static BucketLocalManagerFactory Create(bool zeroAll) => new (zeroAll); + + private BucketLocalManagerFactory(bool zeroAll) + { + _zeroAll = zeroAll; + } + + public BucketLocalManagerFactory(PluginBase plugin) : this(plugin, null) + { } + + public BucketLocalManagerFactory(PluginBase plugin, IConfigScope? config) + { + if (config != null) + { + //Try to get the zero all flag + if (config.TryGetValue("zero_all", out JsonElement zeroEl)) + { + _zeroAll = zeroEl.GetBoolean(); + } + } + } + + protected override void Free() + { + //Free heaps on exit + foreach (BucketLocalManager manager in _managers) + { + manager.Heap.Dispose(); + } + } + + /* + * Buckets are mutually exclusive, so we can use a single heap for each bucket + * to get a little more performance on memory operations + */ + + private sealed record class BucketLocalManager(IUnmangedHeap Heap, uint BucketId, bool Zero) : ICacheEntryMemoryManager + { + + ///<inheritdoc/> + public object AllocHandle(uint size) => Heap.Alloc<byte>(size, Zero); + + ///<inheritdoc/> + public void FreeHandle(object handle) + { + _ = handle ?? throw new ArgumentNullException(nameof(handle)); + MemoryHandle<byte> _handle = Unsafe.As<object, MemoryHandle<byte>>(ref handle); + + //Free the handle + _handle.Dispose(); + } + + ///<inheritdoc/> + public uint GetHandleSize(object handle) + { + _ = handle ?? throw new ArgumentNullException(nameof(handle)); + MemoryHandle<byte> _handle = Unsafe.As<object, MemoryHandle<byte>>(ref handle); + + return (uint)_handle.Length; + } + + ///<inheritdoc/> + public Span<byte> GetSpan(object handle, uint offset, uint length) + { + _ = handle ?? throw new ArgumentNullException(nameof(handle)); + MemoryHandle<byte> _handle = Unsafe.As<object, MemoryHandle<byte>>(ref handle); + + return _handle.GetOffsetSpan(offset, checked((int)length)); + } + + ///<inheritdoc/> + public MemoryHandle PinHandle(object handle, int offset) + { + _ = handle ?? throw new ArgumentNullException(nameof(handle)); + MemoryHandle<byte> _handle = Unsafe.As<object, MemoryHandle<byte>>(ref handle); + + //Pin the handle + return _handle.Pin(offset); + } + + ///<inheritdoc/> + public void ResizeHandle(object handle, uint newSize) + { + _ = handle ?? throw new ArgumentNullException(nameof(handle)); + MemoryHandle<byte> _handle = Unsafe.As<object, MemoryHandle<byte>>(ref handle); + + //Resize the handle + _handle.ResizeIfSmaller(newSize); + } + } + } +} diff --git a/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/EntityCacheExtensions.cs b/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/EntityCacheExtensions.cs index 73baa4a..363e1c9 100644 --- a/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/EntityCacheExtensions.cs +++ b/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/EntityCacheExtensions.cs @@ -54,12 +54,12 @@ namespace VNLib.Plugins.Extensions.VNCache.DataModel /// <param name="cancellation">A token to cancel the operation</param> /// <returns>A task that completes when the delete operation has compelted</returns> /// <exception cref="ArgumentNullException"></exception> - public static Task DeleteAsync<T>(this IGlobalCacheProvider cache, T entity, CancellationToken cancellation) where T: class, ICacheEntity + public static Task RemoveAsync<T>(this IEntityCache<T> cache, T entity, CancellationToken cancellation) where T: class, ICacheEntity { _ = entity ?? throw new ArgumentNullException(nameof(entity)); _ = cache ?? throw new ArgumentNullException(nameof(entity)); //Delete by its id - return cache.DeleteAsync(entity.Id, cancellation); + return cache.RemoveAsync(entity.Id, cancellation); } /// <summary> @@ -71,27 +71,85 @@ namespace VNLib.Plugins.Extensions.VNCache.DataModel /// <param name="entity">The entity to set at the given key</param> /// <returns>A task that completes when the add/update operation has compelted</returns> /// <exception cref="ArgumentNullException"></exception> - public static Task AddOrUpdateAsync<T>(this IGlobalCacheProvider cache, T entity, CancellationToken cancellation) where T: class, ICacheEntity + public static Task UpsertAsync<T>(this IEntityCache<T> cache, T entity, CancellationToken cancellation) where T: class, ICacheEntity { _ = entity ?? throw new ArgumentNullException(nameof(entity)); _ = cache ?? throw new ArgumentNullException(nameof(cache)); //Add/update with its id - return cache.AddOrUpdateAsync(entity.Id, null, entity, cancellation); + return cache.UpsertAsync(entity.Id, entity, cancellation); + } + + /// <summary> + /// Creates an <see cref="IEntityCache{T}"/> wrapper using the current global cache provider. + /// Understand this will share the same cache store as other stores. Consider creating a scoped cache + /// to avoid key collisions + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="cache"></param> + /// <param name="serialier">The entity data serializer</param> + /// <param name="deserializer">The entity data deserializer</param> + /// <returns>The new <see cref="IEntityCache{T}"/> wrapper instance</returns> + /// <exception cref="ArgumentNullException"></exception> + public static IEntityCache<T> CreateEntityCache<T>(this IGlobalCacheProvider cache, ICacheObjectSerialzer serialier, ICacheObjectDeserialzer deserializer) where T: class + { + _ = cache ?? throw new ArgumentNullException(nameof(cache)); + _ = serialier ?? throw new ArgumentNullException(nameof(serialier)); + _ = deserializer ?? throw new ArgumentNullException(nameof(deserializer)); + + return new EntityCacheImpl<T>(cache, deserializer, serialier); + } + + /// <summary> + /// Creates an <see cref="IEntityCache{T}"/> wrapper using the current global cache provider, + /// with a Json serializer/deserializer + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="cache"></param> + /// <returns>The new <see cref="IEntityCache{T}"/> wrapper using json serialization</returns> + /// <exception cref="ArgumentNullException"></exception> + public static IEntityCache<T> CreateJsonEntityCache<T>(this IGlobalCacheProvider cache) where T: class + { + _ = cache ?? throw new ArgumentNullException(nameof(cache)); + JsonCacheObjectSerializer json = new(); + return CreateEntityCache<T>(cache, json, json); + } + + private sealed class EntityCacheImpl<T> : IEntityCache<T> where T : class + { + private readonly IGlobalCacheProvider _cacheProvider; + private readonly ICacheObjectDeserialzer _cacheObjectDeserialzer; + private readonly ICacheObjectSerialzer _cacheObjectSerialzer; + + public EntityCacheImpl(IGlobalCacheProvider cache, ICacheObjectDeserialzer deserializer, ICacheObjectSerialzer serializer) + { + _cacheProvider = cache; + _cacheObjectDeserialzer = deserializer; + _cacheObjectSerialzer = serializer; + } + + ///<inheritdoc/> + public Task<T?> GetAsync(string id, CancellationToken token = default) => _cacheProvider.GetAsync<T>(id, _cacheObjectDeserialzer, token); + + ///<inheritdoc/> + public Task RemoveAsync(string id, CancellationToken token = default) => _cacheProvider.DeleteAsync(id, token); + + ///<inheritdoc/> + public Task UpsertAsync(string id, T entity, CancellationToken token = default) => _cacheProvider.AddOrUpdateAsync(id, null, entity, _cacheObjectSerialzer, token); } - private sealed class ScopedCacheImpl: ScopedCache { private readonly IGlobalCacheProvider cache; + ///<inheritdoc/> public override bool IsConnected { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => cache.IsConnected; } - + ///<inheritdoc/> protected override ICacheKeyGenerator KeyGen { get; } public ScopedCacheImpl(IGlobalCacheProvider cache, ICacheKeyGenerator keyGen) @@ -171,7 +229,7 @@ namespace VNLib.Plugins.Extensions.VNCache.DataModel } ///<inheritdoc/> - public override Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, ICacheObjectSerialzer serialzer, CancellationToken cancellation) + public override Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, CancellationToken cancellation) { _ = key ?? throw new ArgumentNullException(nameof(key)); @@ -181,7 +239,7 @@ namespace VNLib.Plugins.Extensions.VNCache.DataModel //If newkey exists, compute the secondary key string? secondary = newKey != null ? KeyGen.ComputedKey(newKey) : null; - return cache.AddOrUpdateAsync(primary, secondary, rawData, serialzer, cancellation); + return cache.AddOrUpdateAsync(primary, secondary, rawData, cancellation); } } } diff --git a/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/IEntityCache.cs b/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/IEntityCache.cs new file mode 100644 index 0000000..e99591b --- /dev/null +++ b/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/IEntityCache.cs @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Plugins.Extensions.VNCache +* File: IEntityCache.cs +* +* IEntityCache.cs is part of VNLib.Plugins.Extensions.VNCache +* which is part of the larger VNLib collection of libraries and utilities. +* +* VNLib.Plugins.Extensions.VNCache is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* VNLib.Plugins.Extensions.VNCache is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +*/ + +using System.Threading; +using System.Threading.Tasks; + +namespace VNLib.Plugins.Extensions.VNCache.DataModel +{ + /// <summary> + /// Represents a cache that stores referrence type entities + /// </summary> + /// <typeparam name="T">The referrence entity type</typeparam> + public interface IEntityCache<T> where T : class + { + /// <summary> + /// Gets an entity from the cache by its id. Returns null if the entity is not found + /// </summary> + /// <param name="id">The id of the entity to retrieve from the store</param> + /// <param name="token">A token to cancel the operation</param> + /// <returns> The entity if found, null otherwise</returns> + Task<T?> GetAsync(string id, CancellationToken token = default); + + /// <summary> + /// Upserts an entity into the cache by its id. This updates an existing entity + /// or inserts a new one. + /// </summary> + /// <param name="id">The id of the entity to update</param> + /// <param name="entity">A referrence to the entity instance to update</param> + /// <param name="token">A token to cancel the operation</param> + /// <returns>A task that completes when the update has completed successfully</returns> + Task UpsertAsync(string id, T entity, CancellationToken token = default); + + /// <summary> + /// Removes an entity from the cache by its id + /// </summary> + /// <param name="id">The id of the item to remove</param> + /// <param name="token">A token to cancel delete opdation</param> + /// <returns>A task that completes when the item has been deleted successfully</returns> + Task RemoveAsync(string id, CancellationToken token = default); + } + +} diff --git a/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/ScopedCache.cs b/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/ScopedCache.cs index c26fd1a..d949bde 100644 --- a/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/ScopedCache.cs +++ b/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/ScopedCache.cs @@ -65,6 +65,6 @@ namespace VNLib.Plugins.Extensions.VNCache.DataModel public abstract Task GetAsync(string key, IObjectData rawData, CancellationToken cancellation); ///<inheritdoc/> - public abstract Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, ICacheObjectSerialzer serialzer, CancellationToken cancellation); + public abstract Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, CancellationToken cancellation); } } diff --git a/lib/VNLib.Plugins.Extensions.VNCache/src/MemoryCache.cs b/lib/VNLib.Plugins.Extensions.VNCache/src/MemoryCache.cs index e4c95a4..a56529b 100644 --- a/lib/VNLib.Plugins.Extensions.VNCache/src/MemoryCache.cs +++ b/lib/VNLib.Plugins.Extensions.VNCache/src/MemoryCache.cs @@ -3,9 +3,9 @@ * * Library: VNLib * Package: VNLib.Plugins.Extensions.VNCache -* File: RemoteBackedMemoryCache.cs +* File: MemoryCache.cs * -* RemoteBackedMemoryCache.cs is part of VNLib.Plugins.Extensions.VNCache +* MemoryCache.cs is part of VNLib.Plugins.Extensions.VNCache * which is part of the larger VNLib collection of libraries and utilities. * * VNLib.Plugins.Extensions.VNCache is free software: you can redistribute it and/or modify @@ -34,6 +34,7 @@ using VNLib.Utils.Memory.Diagnostics; using VNLib.Data.Caching; using VNLib.Data.Caching.ObjectCache; using VNLib.Plugins.Extensions.Loading; +using VNLib.Data.Caching.ObjectCache.Server; namespace VNLib.Plugins.Extensions.VNCache { @@ -59,6 +60,7 @@ namespace VNLib.Plugins.Extensions.VNCache private readonly ICacheObjectDeserialzer _deserialzer; private readonly IBlobCacheTable _memCache; private readonly IUnmangedHeap _bufferHeap; + private readonly BucketLocalManagerFactory _blobCacheMemManager; public MemoryCache(PluginBase pbase, IConfigScope config) :this( @@ -66,11 +68,10 @@ namespace VNLib.Plugins.Extensions.VNCache pbase.IsDebug(), pbase.Log ) - { - } + { } public MemoryCache(MemoryCacheConfig config):this(config, false, null) - {} + { } private MemoryCache(MemoryCacheConfig config, bool isDebug, ILogProvider? log) { @@ -83,7 +84,7 @@ namespace VNLib.Plugins.Extensions.VNCache IUnmangedHeap newHeap = MemoryUtil.InitializeNewHeapForProcess(); //Wrap in diag heap - _bufferHeap = new TrackedHeapWrapper(newHeap); + _bufferHeap = new TrackedHeapWrapper(newHeap, true); } else { @@ -91,8 +92,10 @@ namespace VNLib.Plugins.Extensions.VNCache _bufferHeap = MemoryUtil.InitializeNewHeapForProcess(); } + _blobCacheMemManager = BucketLocalManagerFactory.Create(config.ZeroAllAllocations); + //Setup cache table - _memCache = new BlobCacheTable(config.TableSize, config.BucketSize, _bufferHeap, null); + _memCache = new BlobCacheTable(config.TableSize, config.BucketSize, _blobCacheMemManager, null); /* * Default to json serialization by using the default @@ -124,13 +127,11 @@ namespace VNLib.Plugins.Extensions.VNCache { _memCache.Dispose(); _bufferHeap.Dispose(); + _blobCacheMemManager.Dispose(); } ///<inheritdoc/> - public Task AddOrUpdateAsync<T>(string key, string? newKey, T value, CancellationToken cancellation) - { - return AddOrUpdateAsync(key, newKey, value, _serialzer, cancellation); - } + public Task AddOrUpdateAsync<T>(string key, string? newKey, T value, CancellationToken cancellation) => AddOrUpdateAsync(key, newKey, value, _serialzer, cancellation); ///<inheritdoc/> public async Task AddOrUpdateAsync<T>(string key, string? newKey, T value, ICacheObjectSerialzer serialzer, CancellationToken cancellation) @@ -164,17 +165,23 @@ namespace VNLib.Plugins.Extensions.VNCache IBlobCacheBucket bucket = _memCache.GetBucket(key); - //Obtain cache handle - using (CacheBucketHandle handle = await bucket.WaitAsync(cancellation)) + //Obtain lock + IBlobCache cache = await bucket.ManualWaitAsync(cancellation); + + try { //Try to read the value - if (handle.Cache.TryGetValue(key, out CacheEntry entry)) + if (cache.TryGetValue(key, out CacheEntry entry)) { - return (T?)deserializer.Deserialze(typeof(T), entry.GetDataSegment()); + return deserializer.Deserialze<T>(entry.GetDataSegment()); } - } - return default; + return default; + } + finally + { + bucket.Release(); + } } ///<inheritdoc/> @@ -185,19 +192,26 @@ namespace VNLib.Plugins.Extensions.VNCache //Get the bucket from the desired key IBlobCacheBucket bucket = _memCache.GetBucket(key); - //Obtain cache handle - using CacheBucketHandle handle = await bucket.WaitAsync(cancellation); - - //Try to read the value - if (handle.Cache.TryGetValue(key, out CacheEntry entry)) + //Obtain lock + IBlobCache cache = await bucket.ManualWaitAsync(cancellation); + + try + { + //Try to read the value + if (cache.TryGetValue(key, out CacheEntry entry)) + { + //Set result data + rawData.SetData(entry.GetDataSegment()); + } + } + finally { - //Set result data - rawData.SetData(entry.GetDataSegment()); + bucket.Release(); } } ///<inheritdoc/> - public Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, ICacheObjectSerialzer serialzer, CancellationToken cancellation) + public Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, CancellationToken cancellation) { Check(); diff --git a/lib/VNLib.Plugins.Extensions.VNCache/src/MemoryCacheConfig.cs b/lib/VNLib.Plugins.Extensions.VNCache/src/MemoryCacheConfig.cs index f34ae91..57c2793 100644 --- a/lib/VNLib.Plugins.Extensions.VNCache/src/MemoryCacheConfig.cs +++ b/lib/VNLib.Plugins.Extensions.VNCache/src/MemoryCacheConfig.cs @@ -81,6 +81,12 @@ namespace VNLib.Plugins.Extensions.VNCache set => RefreshInterval = TimeSpan.FromSeconds(value); } + /// <summary> + /// Zeros all cache entry memory allocations before they are used + /// </summary> + [JsonPropertyName("zero_all")] + public bool ZeroAllAllocations { get; set; } + ///<inheritdoc/> public void Validate() { diff --git a/lib/VNLib.Plugins.Extensions.VNCache/src/RemoteBackedMemoryCache.cs b/lib/VNLib.Plugins.Extensions.VNCache/src/RemoteBackedMemoryCache.cs index 0e92c22..2ab97b8 100644 --- a/lib/VNLib.Plugins.Extensions.VNCache/src/RemoteBackedMemoryCache.cs +++ b/lib/VNLib.Plugins.Extensions.VNCache/src/RemoteBackedMemoryCache.cs @@ -38,6 +38,7 @@ using VNLib.Data.Caching; using VNLib.Data.Caching.ObjectCache; using VNLib.Plugins.Extensions.Loading; using VNLib.Plugins.Extensions.Loading.Events; +using VNLib.Data.Caching.ObjectCache.Server; namespace VNLib.Plugins.Extensions.VNCache { @@ -59,6 +60,7 @@ namespace VNLib.Plugins.Extensions.VNCache private readonly ICacheObjectSerialzer _serialzer; private readonly ICacheObjectDeserialzer _deserialzer; private readonly IBlobCacheTable _memCache; + private readonly BucketLocalManagerFactory? _bucketFactory; public RemoteBackedMemoryCache(PluginBase plugin, IConfigScope config) : base(plugin, config) { @@ -69,8 +71,10 @@ namespace VNLib.Plugins.Extensions.VNCache memCacheConfig.Validate(); + ICacheMemoryManagerFactory manager = plugin.GetOrCreateSingleton<BucketLocalManagerFactory>(); + //Setup cache table - _memCache = new BlobCacheTable(memCacheConfig.TableSize, memCacheConfig.BucketSize, Client.Config.BufferHeap, null); + _memCache = new BlobCacheTable(memCacheConfig.TableSize, memCacheConfig.BucketSize, manager, null); _cacheConfig = memCacheConfig; @@ -92,8 +96,14 @@ namespace VNLib.Plugins.Extensions.VNCache public RemoteBackedMemoryCache(VnCacheClientConfig client, MemoryCacheConfig memCache, ILogProvider? debugLog):base(client, debugLog) { + /* + * Create a local bucket manager factory, we must handle dispal + * however, since its not managed by a plugin + */ + _bucketFactory = BucketLocalManagerFactory.Create(memCache.ZeroAllAllocations); + //Setup mem cache table - _memCache = new BlobCacheTable(memCache.TableSize, memCache.BucketSize, Client.Config.BufferHeap, null); + _memCache = new BlobCacheTable(memCache.TableSize, memCache.BucketSize, _bucketFactory, null); _cacheConfig = memCache; @@ -126,6 +136,7 @@ namespace VNLib.Plugins.Extensions.VNCache finally { _memCache.Dispose(); + _bucketFactory?.Dispose(); } } @@ -164,7 +175,7 @@ namespace VNLib.Plugins.Extensions.VNCache //Try to read the value if (handle.Cache.TryGetValue(key, out CacheEntry entry)) { - return (T?)deserializer.Deserialze(objType, entry.GetDataSegment()); + return deserializer.Deserialze<T>(entry.GetDataSegment()); } } @@ -184,7 +195,7 @@ namespace VNLib.Plugins.Extensions.VNCache await _memCache.AddOrUpdateObjectAsync(key, null, static b => b.GetData(), getBuffer, DateTime.UtcNow, CancellationToken.None); //Deserialze the entity - return (T)deserializer.Deserialze(objType, getBuffer.GetData()); + return deserializer.Deserialze<T>(getBuffer.GetData()); } ///<inheritdoc/> @@ -248,7 +259,7 @@ namespace VNLib.Plugins.Extensions.VNCache } ///<inheritdoc/> - public override async Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, ICacheObjectSerialzer serialzer, CancellationToken cancellation) + public override async Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, CancellationToken cancellation) { CheckConnected(); diff --git a/lib/VNLib.Plugins.Extensions.VNCache/src/VnCacheClient.cs b/lib/VNLib.Plugins.Extensions.VNCache/src/VnCacheClient.cs index b0142a8..e2d0176 100644 --- a/lib/VNLib.Plugins.Extensions.VNCache/src/VnCacheClient.cs +++ b/lib/VNLib.Plugins.Extensions.VNCache/src/VnCacheClient.cs @@ -295,11 +295,11 @@ namespace VNLib.Plugins.Extensions.VNCache } ///<inheritdoc/> - public virtual Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, ICacheObjectSerialzer serialzer, CancellationToken cancellation) + public virtual Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, CancellationToken cancellation) { return !IsConnected ? throw new InvalidOperationException("The underlying client is not connected to a cache node") - : Client!.AddOrUpdateObjectAsync(key, newKey, rawData, serialzer, cancellation); + : Client!.AddOrUpdateObjectAsync(key, newKey, rawData, cancellation); } private sealed class AuthManager : ICacheAuthManager diff --git a/lib/VNLib.Plugins.Extensions.VNCache/src/VnGlobalCache.cs b/lib/VNLib.Plugins.Extensions.VNCache/src/VnGlobalCache.cs index 786a085..4ad6560 100644 --- a/lib/VNLib.Plugins.Extensions.VNCache/src/VnGlobalCache.cs +++ b/lib/VNLib.Plugins.Extensions.VNCache/src/VnGlobalCache.cs @@ -180,9 +180,9 @@ namespace VNLib.Plugins.Extensions.VNCache } ///<inheritdoc/> - public Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, ICacheObjectSerialzer serialzer, CancellationToken cancellation) + public Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, CancellationToken cancellation) { - return _client.AddOrUpdateAsync(key, newKey, rawData, serialzer, cancellation); + return _client.AddOrUpdateAsync(key, newKey, rawData, cancellation); } } }
\ No newline at end of file |