aboutsummaryrefslogtreecommitdiff
path: root/libs/VNLib.Plugins.Sessions.Cache.Client/src
diff options
context:
space:
mode:
Diffstat (limited to 'libs/VNLib.Plugins.Sessions.Cache.Client/src')
-rw-r--r--libs/VNLib.Plugins.Sessions.Cache.Client/src/GlobalCacheStore.cs10
-rw-r--r--libs/VNLib.Plugins.Sessions.Cache.Client/src/IRemoteCacheStore.cs17
-rw-r--r--libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionDataSerialzer.cs47
-rw-r--r--libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionStore.cs9
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)
{