diff options
author | vnugent <public@vaughnnugent.com> | 2023-11-02 01:50:06 -0400 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2023-11-02 01:50:06 -0400 |
commit | 9ddece0eac4dc3718c4f9279b4695d645a3e3cef (patch) | |
tree | 85f24fe1ee6f3845ef5bbb390530ea7e8042bbf2 /libs/VNLib.Plugins.Sessions.Cache.Client/src | |
parent | 43c9196b01799e334bde92e892f0bac47759901a (diff) |
also carried away
Diffstat (limited to 'libs/VNLib.Plugins.Sessions.Cache.Client/src')
4 files changed, 66 insertions, 17 deletions
diff --git a/libs/VNLib.Plugins.Sessions.Cache.Client/src/GlobalCacheStore.cs b/libs/VNLib.Plugins.Sessions.Cache.Client/src/GlobalCacheStore.cs index 89b2b5b..1770f0a 100644 --- a/libs/VNLib.Plugins.Sessions.Cache.Client/src/GlobalCacheStore.cs +++ b/libs/VNLib.Plugins.Sessions.Cache.Client/src/GlobalCacheStore.cs @@ -27,6 +27,7 @@ using System.Threading; using System.Threading.Tasks; using VNLib.Data.Caching; +using VNLib.Utils.Logging; namespace VNLib.Plugins.Sessions.Cache.Client { @@ -40,18 +41,19 @@ namespace VNLib.Plugins.Sessions.Cache.Client private readonly IGlobalCacheProvider _cache; private readonly SessionDataSerialzer _serialzer; - + /// <summary> /// Initiailzes a new <see cref="GlobalCacheStore"/> with the backing <see cref="IGlobalCacheProvider"/> /// global cache /// </summary> /// <param name="globalCache">The backing cache store</param> /// <param name="bufferSize">The size of the buffer used to serialize session objects</param> + /// <param name="debugLog">An optional log provider for writing serializing events to</param> /// <exception cref="ArgumentNullException"></exception> - public GlobalCacheStore(IGlobalCacheProvider globalCache, int bufferSize) + public GlobalCacheStore(IGlobalCacheProvider globalCache, int bufferSize, ILogProvider? debugLog) { _cache = globalCache ?? throw new ArgumentNullException(nameof(globalCache)); - _serialzer = new(bufferSize); + _serialzer = new(bufferSize, debugLog); } ///<inheritdoc/> @@ -64,7 +66,7 @@ namespace VNLib.Plugins.Sessions.Cache.Client } ///<inheritdoc/> - public Task DeleteObjectAsync(string objectId, CancellationToken cancellationToken = default) + public Task<bool> DeleteObjectAsync(string objectId, CancellationToken cancellationToken = default) { return _cache.DeleteAsync(objectId, cancellationToken); } diff --git a/libs/VNLib.Plugins.Sessions.Cache.Client/src/IRemoteCacheStore.cs b/libs/VNLib.Plugins.Sessions.Cache.Client/src/IRemoteCacheStore.cs index aa2e3a7..b876c6c 100644 --- a/libs/VNLib.Plugins.Sessions.Cache.Client/src/IRemoteCacheStore.cs +++ b/libs/VNLib.Plugins.Sessions.Cache.Client/src/IRemoteCacheStore.cs @@ -41,9 +41,24 @@ namespace VNLib.Plugins.Sessions.Cache.Client /// <returns>A task that resolves the found object or null otherwise</returns> Task<T?> GetObjectAsync<T>(string objectId, CancellationToken cancellationToken = default); + /// <summary> + /// Adds or updates an object in the cache provider by session id and optionally it's new id + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="objectId">The session id to add or update</param> + /// <param name="newId">The uniqe id of the item to update</param> + /// <param name="obj"></param> + /// <param name="cancellationToken"></param> + /// <returns></returns> Task AddOrUpdateObjectAsync<T>(string objectId, string? newId, T obj, CancellationToken cancellationToken = default); - Task DeleteObjectAsync(string objectId, CancellationToken cancellationToken = default); + /// <summary> + /// Deletes an object from the cache provider by session id + /// </summary> + /// <param name="objectId">The id of the item to delete</param> + /// <param name="cancellationToken">A token to cancel the operation</param> + /// <returns>A value that indicates if the item was found and deleted</returns> + Task<bool> DeleteObjectAsync(string objectId, CancellationToken cancellationToken = default); /// <summary> /// Gets a value that determines if the remote cache store is available diff --git a/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionDataSerialzer.cs b/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionDataSerialzer.cs index 1cebdf6..94bb1c3 100644 --- a/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionDataSerialzer.cs +++ b/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionDataSerialzer.cs @@ -25,9 +25,11 @@ using System; using System.Text; using System.Buffers; +using System.Diagnostics; using System.Collections.Generic; using VNLib.Utils.Memory; +using VNLib.Utils.Logging; using VNLib.Utils.Extensions; using VNLib.Data.Caching; @@ -38,18 +40,48 @@ namespace VNLib.Plugins.Sessions.Cache.Client /// Very basic session data serializer memory optimized for key-value /// string pairs /// </summary> - internal sealed class SessionDataSerialzer : ICacheObjectSerialzer, ICacheObjectDeserialzer + internal sealed class SessionDataSerialzer : ICacheObjectSerializer, ICacheObjectDeserializer { const string KV_DELIMITER = "\0\0"; readonly int CharBufferSize; + readonly ILogProvider? _debugLog; - public SessionDataSerialzer(int charBufferSize) + public SessionDataSerialzer(int charBufferSize, ILogProvider? debugLog) { CharBufferSize = charBufferSize; + _debugLog = debugLog; + debugLog?.Warn("Sensitive session logging is enabled. This will leak session data!"); } - T? ICacheObjectDeserialzer.Deserialze<T>(ReadOnlySpan<byte> objectData) where T : default + [Conditional("DEBUG")] + private void DebugSessionItems(IDictionary<string, string> sessionData, bool serializing) + { + if (_debugLog is null) + { + return; + } + + StringBuilder sdBuilder = new(); + foreach (KeyValuePair<string, string> item in sessionData) + { + sdBuilder.Append(item.Key); + sdBuilder.Append('='); + sdBuilder.Append(item.Value); + sdBuilder.Append(", "); + } + + if (serializing) + { + _debugLog.Debug("Serialzing session data: {sd} ", sdBuilder); + } + else + { + _debugLog.Debug("Deserialzing session data: {sd} ", sdBuilder); + } + } + + T? ICacheObjectDeserializer.Deserialize<T>(ReadOnlySpan<byte> objectData) where T : default { if (!typeof(T).IsAssignableTo(typeof(IDictionary<string, string>))) { @@ -107,18 +139,23 @@ namespace VNLib.Plugins.Sessions.Cache.Client reader.Advance(sep + 2); } + DebugSessionItems(output, false); + return (T?)(output as object); } private static int GetNextToken(ref ForwardOnlyReader<char> reader) => reader.Window.IndexOf(KV_DELIMITER); - void ICacheObjectSerialzer.Serialize<T>(T obj, IBufferWriter<byte> finiteWriter) + void ICacheObjectSerializer.Serialize<T>(T obj, IBufferWriter<byte> finiteWriter) { if(obj is not Dictionary<string, string> dict) { throw new NotSupportedException("Data type is not supported by this serializer"); } - + + //Write debug info + DebugSessionItems(dict, true); + //Alloc char buffer, sessions should be under 16k using UnsafeMemoryHandle<char> charBuffer = MemoryUtil.UnsafeAllocNearestPage<char>(CharBufferSize); diff --git a/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionStore.cs b/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionStore.cs index 2709a65..0797efb 100644 --- a/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionStore.cs +++ b/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionStore.cs @@ -29,7 +29,6 @@ using System.Collections.Generic; using VNLib.Net.Http; using VNLib.Utils.Logging; -using VNLib.Data.Caching.Exceptions; using VNLib.Plugins.Essentials.Sessions; using VNLib.Plugins.Sessions.Cache.Client.Exceptions; @@ -58,7 +57,7 @@ namespace VNLib.Plugins.Sessions.Cache.Client /// <summary> /// The backing cache store /// </summary> - protected abstract IRemoteCacheStore Cache { get; } + protected abstract IRemoteCacheStore Cache { get; } /// <summary> /// The session factory, produces sessions from their initial data and session-id @@ -307,11 +306,7 @@ namespace VNLib.Plugins.Sessions.Cache.Client try { //Update the session's data async - await Cache.DeleteObjectAsync(session.SessionID); - } - catch(ObjectNotFoundException) - { - //ingore onfe, if the session does not exist in cache + _ = await Cache.DeleteObjectAsync(session.SessionID); } catch (Exception ex) { |