aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar vman <public@vaughnnugent.com>2022-12-28 14:19:32 -0500
committerLibravatar vman <public@vaughnnugent.com>2022-12-28 14:19:32 -0500
commit9bb5ddd8f19c0ecabd7af4ee58d80c16826bc183 (patch)
tree7f8a3863d18f4673294ab11e427fe0b77fd70abf
parent1f2b3530ebeafa162fe4df41e691c33cb2ff0009 (diff)
Cache provider abstractions, reduced deps
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions.OAuth/O2SessionProviderEntry.cs94
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions.OAuth/OAuth2Session.cs5
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions.OAuth/OAuth2SessionProvider.cs14
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions.OAuth/VNLib.Plugins.Essentials.Sessions.OAuth.csproj6
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions.Runtime/VNLib.Plugins.Essentials.Sessions.Runtime.csproj11
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions.Runtime/VnCacheClient.cs201
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions.VNCache/VNLib.Plugins.Essentials.Sessions.VNCache.csproj5
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSession.cs4
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProvider.cs7
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProviderEntry.cs87
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionEntrypoint.cs4
-rw-r--r--Libs/VNLib.Plugins.Essentials.Sessions/VNLib.Plugins.Essentials.Sessions.Memory.csproj2
-rw-r--r--Libs/VNLib.Plugins.Sessions.Cache.Client/GlobalCacheStore.cs64
-rw-r--r--Libs/VNLib.Plugins.Sessions.Cache.Client/IRemoteCacheStore.cs48
-rw-r--r--Libs/VNLib.Plugins.Sessions.Cache.Client/RemoteSession.cs6
-rw-r--r--Libs/VNLib.Plugins.Sessions.Cache.Client/SessionCacheClient.cs16
-rw-r--r--Libs/VNLib.Plugins.Sessions.Cache.Client/VNLib.Plugins.Sessions.Cache.Client.csproj6
-rw-r--r--Plugins/CacheBroker/CacheBroker.csproj2
-rw-r--r--Plugins/CacheBroker/Endpoints/BrokerRegistrationEndpoint.cs5
-rw-r--r--Plugins/SessionCacheServer/Endpoints/BrokerHeartBeat.cs6
-rw-r--r--Plugins/SessionCacheServer/Endpoints/ConnectEndpoint.cs14
-rw-r--r--Plugins/SessionCacheServer/ObjectCacheServer.csproj11
-rw-r--r--Plugins/SessionCacheServer/ObjectCacheServerEntry.cs6
-rw-r--r--Plugins/SessionProvider/GlobalCache.cs165
-rw-r--r--Plugins/SessionProvider/SessionProvider.csproj2
25 files changed, 222 insertions, 569 deletions
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/O2SessionProviderEntry.cs b/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/O2SessionProviderEntry.cs
index f4462a4..7e72714 100644
--- a/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/O2SessionProviderEntry.cs
+++ b/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/O2SessionProviderEntry.cs
@@ -27,12 +27,14 @@ using System.Text.Json;
using VNLib.Net.Http;
using VNLib.Utils.Logging;
using VNLib.Utils.Extensions;
-using VNLib.Data.Caching.Extensions;
+using VNLib.Data.Caching;
+using VNLib.Plugins.Sessions.Cache.Client;
using VNLib.Plugins.Essentials.Oauth.Tokens;
using VNLib.Plugins.Essentials.Oauth.Applications;
using VNLib.Plugins.Essentials.Sessions.OAuth;
using VNLib.Plugins.Essentials.Sessions.Runtime;
using VNLib.Plugins.Essentials.Sessions.OAuth.Endpoints;
+using VNLib.Plugins.Extensions.VNCache;
using VNLib.Plugins.Extensions.Loading;
using VNLib.Plugins.Extensions.Loading.Routing;
using VNLib.Plugins.Extensions.Loading.Sql;
@@ -44,7 +46,6 @@ namespace VNLib.Plugins.Essentials.Sessions.Oauth
public sealed class O2SessionProviderEntry : IRuntimeSessionProvider
{
- const string VNCACHE_CONFIG_KEY = "vncache";
const string OAUTH2_CONFIG_KEY = "oauth2";
private OAuth2SessionProvider? _sessions;
@@ -63,14 +64,11 @@ namespace VNLib.Plugins.Essentials.Sessions.Oauth
void IRuntimeSessionProvider.Load(PluginBase plugin, ILogProvider localized)
{
- //Try get vncache config element
- IReadOnlyDictionary<string, JsonElement> cacheConfig = plugin.GetConfig(VNCACHE_CONFIG_KEY);
-
- IReadOnlyDictionary<string, JsonElement> oauth2Config = plugin.GetConfig(OAUTH2_CONFIG_KEY);
+ IReadOnlyDictionary<string, JsonElement> oauth2Config = plugin.GetConfigForType<OAuth2SessionProvider>();
//Optional application jwt token
Task<JsonDocument?> jwtTokenSecret = plugin.TryGetSecretAsync("application_token_key")
- .ContinueWith(static t => t.Result == null ? null : t.Result.GetJsonDocument(), TaskScheduler.Default);
+ .ContinueWith(static t => t.Result?.GetJsonDocument(), TaskScheduler.Default);
//Access token endpoint is optional
if (oauth2Config.TryGetValue("token_path", out JsonElement el))
@@ -89,74 +87,38 @@ namespace VNLib.Plugins.Essentials.Sessions.Oauth
plugin.Route<RevocationEndpoint>();
}
- //Run
- _ = plugin.DeferTask(() => CacheWokerDoWorkAsync(plugin, localized, cacheConfig, oauth2Config), 100);
-
- }
+ int cacheLimit = oauth2Config["cache_size"].GetInt32();
+ int maxTokensPerApp = oauth2Config["max_tokens_per_app"].GetInt32();
+ int sessionIdSize = (int)oauth2Config["access_token_size"].GetUInt32();
+ TimeSpan tokenValidFor = oauth2Config["token_valid_for_sec"].GetTimeSpan(TimeParseType.Seconds);
+ TimeSpan cleanupInterval = oauth2Config["gc_interval_sec"].GetTimeSpan(TimeParseType.Seconds);
+ string sessionIdPrefix = oauth2Config["cache_prefix"].GetString() ?? throw new KeyNotFoundException($"Missing required key 'cache_prefix' in '{OAUTH2_CONFIG_KEY}' config");
- private async Task<IOAuth2TokenResult?> CreateTokenDelegateAsync(HttpEntity entity, UserApplication app, CancellationToken cancellation)
- {
- return await _sessions!.CreateAccessTokenAsync(entity, app, cancellation).ConfigureAwait(false);
- }
+ //init the id provider
+ OAuth2SessionIdProvider idProv = new(sessionIdPrefix, maxTokensPerApp, sessionIdSize, tokenValidFor);
- /*
- * Starts and monitors the VNCache connection
- */
+ //Get shared global-cache
+ IGlobalCacheProvider globalCache = plugin.GetGlobalCache();
- private async Task CacheWokerDoWorkAsync(PluginBase plugin, ILogProvider localized,
- IReadOnlyDictionary<string, JsonElement> cacheConfig,
- IReadOnlyDictionary<string, JsonElement> oauth2Config)
- {
- //Init cache client
- using VnCacheClient cache = new(plugin.IsDebug() ? localized : null, Utils.Memory.Memory.Shared);
-
- try
- {
- int cacheLimit = oauth2Config["cache_size"].GetInt32();
- int maxTokensPerApp = oauth2Config["max_tokens_per_app"].GetInt32();
- int sessionIdSize = (int)oauth2Config["access_token_size"].GetUInt32();
- TimeSpan tokenValidFor = oauth2Config["token_valid_for_sec"].GetTimeSpan(TimeParseType.Seconds);
- TimeSpan cleanupInterval = oauth2Config["gc_interval_sec"].GetTimeSpan(TimeParseType.Seconds);
- string sessionIdPrefix = oauth2Config["cache_prefix"].GetString() ?? throw new KeyNotFoundException($"Missing required key 'cache_prefix' in '{OAUTH2_CONFIG_KEY}' config");
-
- //init the id provider
- OAuth2SessionIdProvider idProv = new(sessionIdPrefix, maxTokensPerApp, sessionIdSize, tokenValidFor);
-
- //Try loading config
- await cache.LoadConfigAsync(plugin, cacheConfig);
+ //Create cache store from global cache
+ GlobalCacheStore cacheStore = new(globalCache);
- //Init session provider now that client is loaded
- _sessions = new(cache.Resource!, cacheLimit, 100, idProv, plugin.GetContextOptions());
+ //Init session provider now that client is loaded
+ _sessions = new(cacheStore, cacheLimit, 100, idProv, plugin.GetContextOptions());
- //Schedule cleanup interval with the plugin scheduler
- plugin.ScheduleInterval(_sessions, cleanupInterval);
+ //Schedule cleanup interval with the plugin scheduler
+ plugin.ScheduleInterval(_sessions, cleanupInterval);
- localized.Information("Session provider loaded");
+ //Wait and cleanup expired sessions
+ _ = plugin.DeferTask(() => _sessions.CleanupExpiredSessionsAsync(localized, plugin.UnloadToken), 1000);
- //Run and wait for exit
- await cache.RunAsync(localized, plugin.UnloadToken);
+ localized.Information("Session provider loaded");
- }
- catch (OperationCanceledException)
- {}
- catch (KeyNotFoundException e)
- {
- localized.Error("Missing required configuration variable for VnCache client: {0}", e.Message);
- }
- catch(FBMServerNegiationException fne)
- {
- localized.Error("Failed to negotiate connection with cache server {reason}", fne.Message);
- }
- catch (Exception ex)
- {
- localized.Error(ex, "Cache client error occured in session provider");
- }
- finally
- {
- _sessions = null;
- }
+ }
- localized.Information("Cache client exited");
+ private async Task<IOAuth2TokenResult?> CreateTokenDelegateAsync(HttpEntity entity, UserApplication app, CancellationToken cancellation)
+ {
+ return await _sessions!.CreateAccessTokenAsync(entity, app, cancellation).ConfigureAwait(false);
}
}
} \ No newline at end of file
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/OAuth2Session.cs b/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/OAuth2Session.cs
index 539799c..e9a69cd 100644
--- a/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/OAuth2Session.cs
+++ b/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/OAuth2Session.cs
@@ -25,7 +25,6 @@
using System;
using VNLib.Net.Http;
-using VNLib.Net.Messaging.FBM.Client;
using VNLib.Plugins.Sessions.Cache.Client;
using VNLib.Plugins.Sessions.Cache.Client.Exceptions;
@@ -44,10 +43,10 @@ namespace VNLib.Plugins.Essentials.Sessions.OAuth
/// Initalizes a new <see cref="OAuth2Session"/>
/// </summary>
/// <param name="sessionId">The session id (or token)</param>
- /// <param name="client">The <see cref="FBMClient"/> used as the backing cache provider</param>
+ /// <param name="client">The <see cref="IRemoteCacheStore"/> used as the backing cache provider</param>
/// <param name="backgroundTimeOut">The ammount of time to wait for a background operation (delete, update, get)</param>
/// <param name="invalidCache">Called when the session has been marked as invalid and the close even hook is being executed</param>
- public OAuth2Session(string sessionId, FBMClient client, TimeSpan backgroundTimeOut, Action<OAuth2Session> invalidCache)
+ public OAuth2Session(string sessionId, IRemoteCacheStore client, TimeSpan backgroundTimeOut, Action<OAuth2Session> invalidCache)
: base(sessionId, client, backgroundTimeOut)
{
InvalidateCache = invalidCache;
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/OAuth2SessionProvider.cs b/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/OAuth2SessionProvider.cs
index 106029f..dca7909 100644
--- a/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/OAuth2SessionProvider.cs
+++ b/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/OAuth2SessionProvider.cs
@@ -30,14 +30,13 @@ using Microsoft.EntityFrameworkCore;
using VNLib.Net.Http;
using VNLib.Utils;
using VNLib.Utils.Logging;
-using VNLib.Data.Caching;
using VNLib.Data.Caching.Exceptions;
-using VNLib.Net.Messaging.FBM.Client;
using VNLib.Plugins.Sessions.Cache.Client;
using VNLib.Plugins.Essentials.Oauth;
using VNLib.Plugins.Essentials.Oauth.Tokens;
using VNLib.Plugins.Essentials.Oauth.Applications;
using VNLib.Plugins.Extensions.Loading.Events;
+using VNLib.Plugins.Extensions.Loading;
namespace VNLib.Plugins.Essentials.Sessions.OAuth
{
@@ -45,7 +44,8 @@ namespace VNLib.Plugins.Essentials.Sessions.OAuth
/// <summary>
/// Provides OAuth2 session management
/// </summary>
- internal sealed class OAuth2SessionProvider : SessionCacheClient, ISessionProvider, ITokenManager, IIntervalScheduleable
+ [ConfigurationName("oauth2")]
+ internal sealed class OAuth2SessionProvider : SessionCacheClient, ITokenManager, IIntervalScheduleable
{
private static readonly SessionHandle NotFoundHandle = new(null, FileProcessArgs.NotFound, null);
@@ -57,7 +57,7 @@ namespace VNLib.Plugins.Essentials.Sessions.OAuth
private readonly TokenStore TokenStore;
private readonly uint MaxConnections;
- public OAuth2SessionProvider(FBMClient client, int maxCacheItems, uint maxConnections, IOauthSessionIdFactory idFactory, DbContextOptions dbCtx)
+ public OAuth2SessionProvider(IRemoteCacheStore client, int maxCacheItems, uint maxConnections, IOauthSessionIdFactory idFactory, DbContextOptions dbCtx)
: base(client, maxCacheItems)
{
factory = idFactory;
@@ -66,7 +66,7 @@ namespace VNLib.Plugins.Essentials.Sessions.OAuth
}
///<inheritdoc/>
- protected override RemoteSession SessionCtor(string sessionId) => new OAuth2Session(sessionId, Client, BackgroundTimeout, InvalidatateCache);
+ protected override RemoteSession SessionCtor(string sessionId) => new OAuth2Session(sessionId, Store, BackgroundTimeout, InvalidatateCache);
private void InvalidatateCache(OAuth2Session session)
{
@@ -97,7 +97,7 @@ namespace VNLib.Plugins.Essentials.Sessions.OAuth
if (WaitingConnections > MaxConnections)
{
//Set 503 for temporary unavail
- entity.CloseResponse(System.Net.HttpStatusCode.ServiceUnavailable);
+ entity.CloseResponse(HttpStatusCode.ServiceUnavailable);
return new SessionHandle(null, FileProcessArgs.VirtualSkip, null);
}
@@ -202,7 +202,7 @@ namespace VNLib.Plugins.Essentials.Sessions.OAuth
try
{
//Remove tokens by thier object id from cache
- await base.Client.DeleteObjectAsync(token.Id, cancellationToken);
+ await base.Store.DeleteObjectAsync(token.Id, cancellationToken);
}
//Ignore if the object has already been removed
catch (ObjectNotFoundException)
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/VNLib.Plugins.Essentials.Sessions.OAuth.csproj b/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/VNLib.Plugins.Essentials.Sessions.OAuth.csproj
index e9927b5..d6775c8 100644
--- a/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/VNLib.Plugins.Essentials.Sessions.OAuth.csproj
+++ b/Libs/VNLib.Plugins.Essentials.Sessions.OAuth/VNLib.Plugins.Essentials.Sessions.OAuth.csproj
@@ -13,7 +13,8 @@
<Version>1.0.1.1</Version>
<PackageProjectUrl>https://www.vaughnugent.com</PackageProjectUrl>
<AnalysisLevel>latest-all</AnalysisLevel>
-
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\StrongNameingKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -34,11 +35,10 @@
<ProjectReference Include="..\..\..\..\VNLib\Http\src\VNLib.Net.Http.csproj" />
<ProjectReference Include="..\..\..\..\VNLib\Plugins\src\VNLib.Plugins.csproj" />
<ProjectReference Include="..\..\..\..\VNLib\Utils\src\VNLib.Utils.csproj" />
- <ProjectReference Include="..\..\..\DataCaching\VNLib.Data.Caching.Extensions\VNLib.Data.Caching.Extensions.csproj" />
- <ProjectReference Include="..\..\..\DataCaching\VNLib.Data.Caching\src\VNLib.Data.Caching.csproj" />
<ProjectReference Include="..\..\..\Extensions\VNLib.Plugins.Extensions.Loading.Sql\VNLib.Plugins.Extensions.Loading.Sql.csproj" />
<ProjectReference Include="..\..\..\Extensions\VNLib.Plugins.Extensions.Loading\VNLib.Plugins.Extensions.Loading.csproj" />
<ProjectReference Include="..\..\..\Extensions\VNLib.Plugins.Extensions.Validation\VNLib.Plugins.Extensions.Validation.csproj" />
+ <ProjectReference Include="..\..\..\Extensions\VNLib.Plugins.Extensions.VNCache\VNLib.Plugins.Extensions.VNCache.csproj" />
<ProjectReference Include="..\..\..\Oauth\Libs\VNLib.Plugins.Essentials.Oauth\VNLib.Plugins.Essentials.Oauth.csproj" />
<ProjectReference Include="..\..\..\PluginBase\VNLib.Plugins.PluginBase.csproj" />
<ProjectReference Include="..\VNLib.Plugins.Essentials.Sessions.Runtime\VNLib.Plugins.Essentials.Sessions.Runtime.csproj" />
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.Runtime/VNLib.Plugins.Essentials.Sessions.Runtime.csproj b/Libs/VNLib.Plugins.Essentials.Sessions.Runtime/VNLib.Plugins.Essentials.Sessions.Runtime.csproj
index cf6d0c9..87c29e8 100644
--- a/Libs/VNLib.Plugins.Essentials.Sessions.Runtime/VNLib.Plugins.Essentials.Sessions.Runtime.csproj
+++ b/Libs/VNLib.Plugins.Essentials.Sessions.Runtime/VNLib.Plugins.Essentials.Sessions.Runtime.csproj
@@ -6,17 +6,22 @@
<Nullable>enable</Nullable>
<Authors>Vaughn Nugent</Authors>
<Copyright>Copyright © 2022 Vaughn Nugent</Copyright>
- <Version>1.0.1.1</Version>
+ <Version>1.0.1.2</Version>
<SignAssembly>False</SignAssembly>
<PackageProjectUrl>https://www.vaughnnugent.com/resources</PackageProjectUrl>
- <GenerateDocumentationFile>True</GenerateDocumentationFile>
<AnalysisLevel>latest-all</AnalysisLevel>
+ <GenerateDocumentationFile>True</GenerateDocumentationFile>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\StrongNameingKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" />
+
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'" />
+
<ItemGroup>
<ProjectReference Include="..\..\..\..\VNLib\Essentials\src\VNLib.Plugins.Essentials.csproj" />
<ProjectReference Include="..\..\..\..\VNLib\Http\src\VNLib.Net.Http.csproj" />
- <ProjectReference Include="..\..\..\DataCaching\VNLib.Data.Caching.Extensions\VNLib.Data.Caching.Extensions.csproj" />
<ProjectReference Include="..\..\..\Extensions\VNLib.Plugins.Extensions.Loading\VNLib.Plugins.Extensions.Loading.csproj" />
<ProjectReference Include="..\..\..\PluginBase\VNLib.Plugins.PluginBase.csproj" />
</ItemGroup>
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.Runtime/VnCacheClient.cs b/Libs/VNLib.Plugins.Essentials.Sessions.Runtime/VnCacheClient.cs
deleted file mode 100644
index 2f7bdf2..0000000
--- a/Libs/VNLib.Plugins.Essentials.Sessions.Runtime/VnCacheClient.cs
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
-* Copyright (c) 2022 Vaughn Nugent
-*
-* Library: VNLib
-* Package: VNLib.Plugins.Essentials.Sessions.Runtime
-* File: VnCacheClient.cs
-*
-* VnCacheClient.cs is part of VNLib.Plugins.Essentials.Sessions.Runtime which is part of the larger
-* VNLib collection of libraries and utilities.
-*
-* VNLib.Plugins.Essentials.Sessions.Runtime 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.Essentials.Sessions.Runtime 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.Text.Json;
-using System.Net.Sockets;
-using System.Net.WebSockets;
-using System.Security.Cryptography;
-
-using VNLib.Utils.Memory;
-using VNLib.Utils.Logging;
-using VNLib.Utils.Resources;
-using VNLib.Utils.Extensions;
-using VNLib.Data.Caching.Extensions;
-using VNLib.Net.Messaging.FBM.Client;
-using VNLib.Plugins.Extensions.Loading;
-using VNLib.Hashing.IdentityUtility;
-
-namespace VNLib.Plugins.Essentials.Sessions.Runtime
-{
- /// <summary>
- /// A wrapper to simplify a cache client object
- /// </summary>
- public sealed class VnCacheClient : OpenResourceHandle<FBMClient?>
- {
- FBMClient? _client;
-
- /// <summary>
- /// The wrapped client
- /// </summary>
- public override FBMClient? Resource => _client;
-
-
- private TimeSpan RetryInterval;
-
- private readonly ILogProvider? DebugLog;
- private readonly IUnmangedHeap? ClientHeap;
-
- /// <summary>
- /// Initializes an emtpy client wrapper that still requires
- /// configuration loading
- /// </summary>
- /// <param name="debugLog">An optional debugging log</param>
- /// <param name="heap">An optional <see cref="IUnmangedHeap"/> for <see cref="FBMClient"/> buffers</param>
- public VnCacheClient(ILogProvider? debugLog, IUnmangedHeap? heap = null)
- {
- DebugLog = debugLog;
- //Default to 10 seconds
- RetryInterval = TimeSpan.FromSeconds(10);
-
- ClientHeap = heap;
- }
-
- ///<inheritdoc/>
- protected override void Free()
- {
- _client?.Dispose();
- _client = null;
- }
-
- /// <summary>
- /// Loads required configuration variables from the config store and
- /// intializes the interal client
- /// </summary>
- /// <param name="pbase"></param>
- /// <param name="config">A dictionary of configuration varables</param>
- /// <exception cref="KeyNotFoundException"></exception>
- public async Task LoadConfigAsync(PluginBase pbase, IReadOnlyDictionary<string, JsonElement> config)
- {
- int maxMessageSize = config["max_message_size"].GetInt32();
- string? brokerAddress = config["broker_address"].GetString() ?? throw new KeyNotFoundException("Missing required configuration variable broker_address");
-
- //Get keys async
- Task<SecretResult?> clientPrivTask = pbase.TryGetSecretAsync("client_private_key");
- Task<SecretResult?> brokerPubTask = pbase.TryGetSecretAsync("broker_public_key");
- Task<SecretResult?> cachePubTask = pbase.TryGetSecretAsync("cache_public_key");
-
- //Wait for all tasks to complete
- _ = await Task.WhenAll(clientPrivTask, brokerPubTask, cachePubTask);
-
- using SecretResult clientPriv = await clientPrivTask ?? throw new KeyNotFoundException("Missing required secret client_private_key");
- using SecretResult brokerPub = await brokerPubTask ?? throw new KeyNotFoundException("Missing required secret broker_public_key");
- using SecretResult cachePub = await cachePubTask ?? throw new KeyNotFoundException("Missing required secret cache_public_key");
-
- ReadOnlyJsonWebKey clientCert = clientPriv.GetJsonWebKey();
- ReadOnlyJsonWebKey brokerPubKey = brokerPub.GetJsonWebKey();
- ReadOnlyJsonWebKey cachePubKey = cachePub.GetJsonWebKey();
-
- RetryInterval = config["retry_interval_sec"].GetTimeSpan(TimeParseType.Seconds);
-
- Uri brokerUri = new(brokerAddress);
-
- //Init the client with default settings
- FBMClientConfig conf = FBMDataCacheExtensions.GetDefaultConfig(ClientHeap ?? Memory.Shared, maxMessageSize, DebugLog);
-
- _client = new(conf);
-
- //Add the configuration to the client
- _client.GetCacheConfiguration()
- .WithBroker(brokerUri)
- .WithVerificationKey(cachePubKey)
- .WithSigningCertificate(clientCert)
- .WithBrokerVerificationKey(brokerPubKey)
- .WithTls(brokerUri.Scheme == Uri.UriSchemeHttps);
- }
-
- /// <summary>
- /// Discovers nodes in the configured cluster and connects to a random node
- /// </summary>
- /// <param name="Log">A <see cref="ILogProvider"/> to write log events to</param>
- /// <param name="cancellationToken">A token to cancel the operation</param>
- /// <returns>A task that completes when the operation has been cancelled or an unrecoverable error occured</returns>
- /// <exception cref="InvalidOperationException"></exception>
- /// <exception cref="OperationCanceledException"></exception>
- public async Task RunAsync(ILogProvider Log, CancellationToken cancellationToken)
- {
- _ = Resource ?? throw new InvalidOperationException("Client configuration not loaded, cannot connect to cache servers");
-
- while (true)
- {
- //Load the server list
- ActiveServer[]? servers;
- while (true)
- {
- try
- {
- Log.Debug("Discovering cluster nodes in broker");
- //Get server list
- servers = await Resource.DiscoverCacheNodesAsync(cancellationToken);
- break;
- }
- catch (HttpRequestException re) when (re.InnerException is SocketException)
- {
- Log.Warn("Broker server is unreachable");
- }
- catch (Exception ex)
- {
- Log.Warn("Failed to get server list from broker, reason {r}", ex.Message);
- }
-
- //Gen random ms delay
- int randomMsDelay = RandomNumberGenerator.GetInt32(1000, 2000);
- await Task.Delay(randomMsDelay, cancellationToken);
- }
-
- if (servers?.Length == 0)
- {
- Log.Warn("No cluster nodes found, retrying");
- await Task.Delay(RetryInterval, cancellationToken);
- continue;
- }
-
- try
- {
- Log.Debug("Connecting to random cache server");
-
- //Connect to a random server
- ActiveServer selected = await Resource.ConnectToRandomCacheAsync(cancellationToken);
- Log.Debug("Connected to cache server {s}", selected.ServerId);
-
- //Wait for disconnect
- await Resource.WaitForExitAsync(cancellationToken);
-
- Log.Debug("Cache server disconnected");
- }
- catch (WebSocketException wse)
- {
- Log.Warn("Failed to connect to cache server {reason}", wse.Message);
- continue;
- }
- catch (HttpRequestException he) when (he.InnerException is SocketException)
- {
- Log.Debug("Failed to connect to random cache server server");
- //Continue next loop
- continue;
- }
- }
- }
- }
-}
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/VNLib.Plugins.Essentials.Sessions.VNCache.csproj b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/VNLib.Plugins.Essentials.Sessions.VNCache.csproj
index dc73ed8..9895eea 100644
--- a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/VNLib.Plugins.Essentials.Sessions.VNCache.csproj
+++ b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/VNLib.Plugins.Essentials.Sessions.VNCache.csproj
@@ -14,6 +14,8 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<AnalysisLevel>latest-all</AnalysisLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\StrongNameingKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
@@ -23,9 +25,8 @@
<ItemGroup>
<ProjectReference Include="..\..\..\..\VNLib\Http\src\VNLib.Net.Http.csproj" />
<ProjectReference Include="..\..\..\..\VNLib\Utils\src\VNLib.Utils.csproj" />
- <ProjectReference Include="..\..\..\DataCaching\VNLib.Data.Caching.Extensions\VNLib.Data.Caching.Extensions.csproj" />
- <ProjectReference Include="..\..\..\DataCaching\VNLib.Data.Caching\src\VNLib.Data.Caching.csproj" />
<ProjectReference Include="..\..\..\Extensions\VNLib.Plugins.Extensions.Loading\VNLib.Plugins.Extensions.Loading.csproj" />
+ <ProjectReference Include="..\..\..\Extensions\VNLib.Plugins.Extensions.VNCache\VNLib.Plugins.Extensions.VNCache.csproj" />
<ProjectReference Include="..\..\..\PluginBase\VNLib.Plugins.PluginBase.csproj" />
<ProjectReference Include="..\VNLib.Plugins.Essentials.Sessions.Runtime\VNLib.Plugins.Essentials.Sessions.Runtime.csproj" />
<ProjectReference Include="..\VNLib.Plugins.Sessions.Cache.Client\VNLib.Plugins.Sessions.Cache.Client.csproj" />
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSession.cs b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSession.cs
index cd5657d..87e08e7 100644
--- a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSession.cs
+++ b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSession.cs
@@ -23,8 +23,6 @@
*/
using VNLib.Net.Http;
-using VNLib.Data.Caching;
-using VNLib.Net.Messaging.FBM.Client;
using VNLib.Plugins.Essentials.Extensions;
using VNLib.Plugins.Sessions.Cache.Client;
using static VNLib.Plugins.Essentials.Sessions.ISessionExtensions;
@@ -38,7 +36,7 @@ namespace VNLib.Plugins.Essentials.Sessions.VNCache
protected readonly Func<IHttpEvent, string, string> UpdateId;
private string? _oldId;
- public WebSession(string sessionId, FBMClient client, TimeSpan backgroundTimeOut, Func<IHttpEvent, string, string> UpdateId)
+ public WebSession(string sessionId, IRemoteCacheStore client, TimeSpan backgroundTimeOut, Func<IHttpEvent, string, string> UpdateId)
: base(sessionId, client, backgroundTimeOut)
{
this.UpdateId = UpdateId;
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProvider.cs b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProvider.cs
index 5747175..ebc3c3d 100644
--- a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProvider.cs
+++ b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProvider.cs
@@ -25,7 +25,7 @@
using System;
using VNLib.Net.Http;
-using VNLib.Net.Messaging.FBM.Client;
+using VNLib.Plugins.Extensions.Loading;
using VNLib.Plugins.Sessions.Cache.Client;
namespace VNLib.Plugins.Essentials.Sessions.VNCache
@@ -33,6 +33,7 @@ namespace VNLib.Plugins.Essentials.Sessions.VNCache
/// <summary>
/// The implementation of a VNCache web based session
/// </summary>
+ [ConfigurationName("web")]
internal sealed class WebSessionProvider : SessionCacheClient, ISessionProvider
{
static readonly TimeSpan BackgroundUpdateTimeout = TimeSpan.FromSeconds(10);
@@ -47,7 +48,7 @@ namespace VNLib.Plugins.Essentials.Sessions.VNCache
/// <param name="maxCacheItems">The max number of items to store in cache</param>
/// <param name="maxWaiting">The maxium number of waiting session events before 503s are sent</param>
/// <param name="factory">The session-id factory</param>
- public WebSessionProvider(FBMClient client, int maxCacheItems, uint maxWaiting, IWebSessionIdFactory factory) : base(client, maxCacheItems)
+ public WebSessionProvider(IRemoteCacheStore client, int maxCacheItems, uint maxWaiting, IWebSessionIdFactory factory) : base(client, maxCacheItems)
{
this.factory = factory;
MaxConnections = maxWaiting;
@@ -69,7 +70,7 @@ namespace VNLib.Plugins.Essentials.Sessions.VNCache
return newid;
}
- protected override RemoteSession SessionCtor(string sessionId) => new WebSession(sessionId, Client, BackgroundUpdateTimeout, UpdateSessionId);
+ protected override RemoteSession SessionCtor(string sessionId) => new WebSession(sessionId, Store, BackgroundUpdateTimeout, UpdateSessionId);
public async ValueTask<SessionHandle> GetSessionAsync(IHttpEvent entity, CancellationToken cancellationToken)
{
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProviderEntry.cs b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProviderEntry.cs
index 8e25416..309db47 100644
--- a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProviderEntry.cs
+++ b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProviderEntry.cs
@@ -25,29 +25,26 @@
using System.Text.Json;
using VNLib.Net.Http;
-using VNLib.Utils.Memory;
using VNLib.Utils.Logging;
using VNLib.Utils.Extensions;
-using VNLib.Plugins.Extensions.Loading;
+using VNLib.Data.Caching;
+using VNLib.Plugins.Sessions.Cache.Client;
using VNLib.Plugins.Essentials.Sessions.Runtime;
-using VNLib.Data.Caching.Extensions;
+using VNLib.Plugins.Extensions.Loading;
+using VNLib.Plugins.Extensions.VNCache;
namespace VNLib.Plugins.Essentials.Sessions.VNCache
{
public sealed class WebSessionProviderEntry : IRuntimeSessionProvider
{
- const string VNCACHE_CONFIG_KEY = "vncache";
const string WEB_SESSION_CONFIG = "web";
private WebSessionProvider? _sessions;
- public bool CanProcess(IHttpEvent entity)
- {
- //Web sessions can always be provided so long as cache is loaded
- return _sessions != null;
- }
+ //Web sessions can always be provided so long as cache is loaded
+ bool IRuntimeSessionProvider.CanProcess(IHttpEvent entity) => _sessions != null;
- public ValueTask<SessionHandle> GetSessionAsync(IHttpEvent entity, CancellationToken cancellationToken)
+ ValueTask<SessionHandle> ISessionProvider.GetSessionAsync(IHttpEvent entity, CancellationToken cancellationToken)
{
return _sessions!.GetSessionAsync(entity, cancellationToken);
}
@@ -55,77 +52,31 @@ namespace VNLib.Plugins.Essentials.Sessions.VNCache
void IRuntimeSessionProvider.Load(PluginBase plugin, ILogProvider localized)
{
//Try get vncache config element
- IReadOnlyDictionary<string, JsonElement> cacheConfig = plugin.GetConfig(VNCACHE_CONFIG_KEY);
-
- IReadOnlyDictionary<string, JsonElement> webSessionConfig = plugin.GetConfig(WEB_SESSION_CONFIG);
+ IReadOnlyDictionary<string, JsonElement> webSessionConfig = plugin.GetConfigForType<WebSessionProvider>();
uint cookieSize = webSessionConfig["cookie_size"].GetUInt32();
string cookieName = webSessionConfig["cookie_name"].GetString() ?? throw new KeyNotFoundException($"Missing required element 'cookie_name' for config '{WEB_SESSION_CONFIG}'");
string cachePrefix = webSessionConfig["cache_prefix"].GetString() ?? throw new KeyNotFoundException($"Missing required element 'cache_prefix' for config '{WEB_SESSION_CONFIG}'");
+ int cacheLimit = (int)webSessionConfig["cache_size"].GetUInt32();
+ uint maxConnections = webSessionConfig["max_waiting_connections"].GetUInt32();
TimeSpan validFor = webSessionConfig["valid_for_sec"].GetTimeSpan(TimeParseType.Seconds);
//Init id factory
WebSessionIdFactoryImpl idFactory = new(cookieSize, cookieName, cachePrefix, validFor);
- //Run client connection
- _ = plugin.DeferTask(() => WokerDoWorkAsync(plugin, localized, idFactory, cacheConfig, webSessionConfig));
- }
-
-
- /*
- * Starts and monitors the VNCache connection
- */
-
- private async Task WokerDoWorkAsync(
- PluginBase plugin,
- ILogProvider localized,
- WebSessionIdFactoryImpl idFactory,
- IReadOnlyDictionary<string, JsonElement> cacheConfig,
- IReadOnlyDictionary<string, JsonElement> webSessionConfig)
- {
- //Init cache client
- using VnCacheClient cache = new(plugin.IsDebug() ? localized : null, Memory.Shared);
-
- try
- {
- int cacheLimit = (int)webSessionConfig["cache_size"].GetUInt32();
- uint maxConnections = webSessionConfig["max_waiting_connections"].GetUInt32();
-
- //Try loading config
- await cache.LoadConfigAsync(plugin, cacheConfig);
-
- //Init provider
- _sessions = new(cache.Resource!, cacheLimit, maxConnections, idFactory);
-
- localized.Information("Session provider loaded");
+ //Get shared global-cache
+ IGlobalCacheProvider globalCache = plugin.GetGlobalCache();
- //Listen for cache table events
- _ = plugin.DeferTask(() => _sessions.CleanupExpiredSessionsAsync(localized, plugin.UnloadToken));
+ //Create cache store from global cache
+ GlobalCacheStore cacheStore = new(globalCache);
- //Run and wait for exit
- await cache.RunAsync(localized, plugin.UnloadToken);
+ //Init provider
+ _sessions = new(cacheStore, cacheLimit, maxConnections, idFactory);
- }
- catch (OperationCanceledException)
- { }
- catch (KeyNotFoundException e)
- {
- localized.Error("Missing required configuration variable for VnCache client: {0}", e.Message);
- }
- catch (FBMServerNegiationException fne)
- {
- localized.Error("Failed to negotiate connection with cache server {reason}", fne.Message);
- }
- catch (Exception ex)
- {
- localized.Error(ex, "Cache client error occured in session provider");
- }
- finally
- {
- _sessions = null;
- }
+ //Load and run cached sessions on deferred task lib
+ _ = plugin.DeferTask(() => _sessions.CleanupExpiredSessionsAsync(localized, plugin.UnloadToken), 1000);
- localized.Information("Cache client exited");
+ localized.Information("Session provider loaded");
}
}
} \ No newline at end of file
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionEntrypoint.cs b/Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionEntrypoint.cs
index f58129a..07ae04b 100644
--- a/Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionEntrypoint.cs
+++ b/Libs/VNLib.Plugins.Essentials.Sessions/MemorySessionEntrypoint.cs
@@ -77,10 +77,10 @@ namespace VNLib.Plugins.Essentials.Sessions.Memory
_ = plugin.DeferTask(() => _sessions.CleanupExiredAsync(localized, plugin.UnloadToken));
//Schedule garbage collector
- _ = plugin.ScheduleInterval(this, TimeSpan.FromMinutes(1));
+ plugin.ScheduleInterval(this, TimeSpan.FromMinutes(1));
//Call cleanup on exit
- _ = plugin.UnloadToken.RegisterUnobserved(_sessions.Cleanup);
+ _ = plugin.RegisterForUnload(_sessions.Cleanup);
}
Task IIntervalScheduleable.OnIntervalAsync(ILogProvider log, CancellationToken cancellationToken)
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions/VNLib.Plugins.Essentials.Sessions.Memory.csproj b/Libs/VNLib.Plugins.Essentials.Sessions/VNLib.Plugins.Essentials.Sessions.Memory.csproj
index c4a65f5..78fe298 100644
--- a/Libs/VNLib.Plugins.Essentials.Sessions/VNLib.Plugins.Essentials.Sessions.Memory.csproj
+++ b/Libs/VNLib.Plugins.Essentials.Sessions/VNLib.Plugins.Essentials.Sessions.Memory.csproj
@@ -8,6 +8,8 @@
<Authors>Vaughn Nugent</Authors>
<Copyright>Copyright © 2022 Vaughn Nugent</Copyright>
<PackageProjectUrl>https://www.vaughnnugent.com/resources</PackageProjectUrl>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\StrongNameingKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<!-- Resolve nuget dll files and store them in the output dir -->
diff --git a/Libs/VNLib.Plugins.Sessions.Cache.Client/GlobalCacheStore.cs b/Libs/VNLib.Plugins.Sessions.Cache.Client/GlobalCacheStore.cs
new file mode 100644
index 0000000..df3c564
--- /dev/null
+++ b/Libs/VNLib.Plugins.Sessions.Cache.Client/GlobalCacheStore.cs
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2022 Vaughn Nugent
+*
+* Library: VNLib
+* Package: VNLib.Plugins.Sessions.Cache.Client
+* File: GlobalCacheStore.cs
+*
+* GlobalCacheStore.cs is part of VNLib.Plugins.Sessions.Cache.Client which is part of the larger
+* VNLib collection of libraries and utilities.
+*
+* VNLib.Plugins.Sessions.Cache.Client 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.Sessions.Cache.Client 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.Threading;
+using System.Threading.Tasks;
+
+using VNLib.Data.Caching;
+
+namespace VNLib.Plugins.Sessions.Cache.Client
+{
+ /// <summary>
+ /// A wrapper class to provide a <see cref="IRemoteCacheStore"/> from
+ /// a <see cref="IGlobalCacheProvider"/> client instance
+ /// </summary>
+ public sealed class GlobalCacheStore : IRemoteCacheStore
+ {
+ private readonly IGlobalCacheProvider _cache;
+
+ public GlobalCacheStore(IGlobalCacheProvider globalCache)
+ {
+ _cache = globalCache ?? throw new ArgumentNullException(nameof(globalCache));
+ }
+
+ ///<inheritdoc/>
+ public Task AddOrUpdateObjectAsync<T>(string objectId, string? newId, T obj, CancellationToken cancellationToken = default)
+ {
+ return _cache.AddOrUpdateAsync(objectId, newId, obj, cancellationToken);
+ }
+
+ ///<inheritdoc/>
+ public Task DeleteObjectAsync(string objectId, CancellationToken cancellationToken = default)
+ {
+ return _cache.DeleteAsync(objectId, cancellationToken);
+ }
+
+ ///<inheritdoc/>
+ public Task<T?> GetObjectAsync<T>(string objectId, CancellationToken cancellationToken = default)
+ {
+ return _cache.GetAsync<T>(objectId, cancellationToken);
+ }
+ }
+}
diff --git a/Libs/VNLib.Plugins.Sessions.Cache.Client/IRemoteCacheStore.cs b/Libs/VNLib.Plugins.Sessions.Cache.Client/IRemoteCacheStore.cs
new file mode 100644
index 0000000..2a8bd49
--- /dev/null
+++ b/Libs/VNLib.Plugins.Sessions.Cache.Client/IRemoteCacheStore.cs
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2022 Vaughn Nugent
+*
+* Library: VNLib
+* Package: VNLib.Plugins.Sessions.Cache.Client
+* File: IRemoteCacheStore.cs
+*
+* IRemoteCacheStore.cs is part of VNLib.Plugins.Sessions.Cache.Client which is part of the larger
+* VNLib collection of libraries and utilities.
+*
+* VNLib.Plugins.Sessions.Cache.Client 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.Sessions.Cache.Client 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.Sessions.Cache.Client
+{
+ /// <summary>
+ /// Represents an asynchronous interface to a remote cache store
+ /// </summary>
+ public interface IRemoteCacheStore
+ {
+ /// <summary>
+ /// Gets an object from the cache provider by key
+ /// </summary>
+ /// <typeparam name="T">The data type</typeparam>
+ /// <param name="objectId">The key/id of the object to recover</param>
+ /// <param name="cancellationToken">A token to cancel the operation</param>
+ /// <returns>A task that resolves the found object or null otherwise</returns>
+ Task<T?> GetObjectAsync<T>(string objectId, CancellationToken cancellationToken = default);
+
+ Task AddOrUpdateObjectAsync<T>(string objectId, string? newId, T obj, CancellationToken cancellationToken = default);
+
+ Task DeleteObjectAsync(string objectId, CancellationToken cancellationToken = default);
+ }
+}
diff --git a/Libs/VNLib.Plugins.Sessions.Cache.Client/RemoteSession.cs b/Libs/VNLib.Plugins.Sessions.Cache.Client/RemoteSession.cs
index 3b61f68..af2c969 100644
--- a/Libs/VNLib.Plugins.Sessions.Cache.Client/RemoteSession.cs
+++ b/Libs/VNLib.Plugins.Sessions.Cache.Client/RemoteSession.cs
@@ -30,10 +30,8 @@ using System.Collections.Generic;
using Microsoft.VisualStudio.Threading;
using VNLib.Net.Http;
-using VNLib.Data.Caching;
using VNLib.Data.Caching.Exceptions;
using VNLib.Utils.Extensions;
-using VNLib.Net.Messaging.FBM.Client;
using VNLib.Plugins.Essentials.Sessions;
using VNLib.Plugins.Essentials.Extensions;
@@ -47,7 +45,7 @@ namespace VNLib.Plugins.Sessions.Cache.Client
{
protected const string CREATED_TIME_ENTRY = "__.i.ctime";
- protected FBMClient Client { get; }
+ protected IRemoteCacheStore Client { get; }
protected TimeSpan UpdateTimeout { get; }
private readonly AsyncLazyInitializer Initializer;
@@ -57,7 +55,7 @@ namespace VNLib.Plugins.Sessions.Cache.Client
/// </summary>
protected Dictionary<string, string>? DataStore;
- protected RemoteSession(string sessionId, FBMClient client, TimeSpan backgroundTimeOut)
+ protected RemoteSession(string sessionId, IRemoteCacheStore client, TimeSpan backgroundTimeOut)
{
SessionID = sessionId;
UpdateTimeout = backgroundTimeOut;
diff --git a/Libs/VNLib.Plugins.Sessions.Cache.Client/SessionCacheClient.cs b/Libs/VNLib.Plugins.Sessions.Cache.Client/SessionCacheClient.cs
index 2e72391..800ad66 100644
--- a/Libs/VNLib.Plugins.Sessions.Cache.Client/SessionCacheClient.cs
+++ b/Libs/VNLib.Plugins.Sessions.Cache.Client/SessionCacheClient.cs
@@ -32,7 +32,6 @@ using VNLib.Net.Http;
using VNLib.Utils.Async;
using VNLib.Utils.Logging;
using VNLib.Utils.Memory.Caching;
-using VNLib.Net.Messaging.FBM.Client;
using VNLib.Plugins.Essentials.Sessions;
namespace VNLib.Plugins.Sessions.Cache.Client
@@ -97,19 +96,19 @@ namespace VNLib.Plugins.Sessions.Cache.Client
/// <summary>
/// The client used to communicate with the cache server
/// </summary>
- protected FBMClient Client { get; }
+ protected IRemoteCacheStore Store { get; }
/// <summary>
/// Initializes a new <see cref="SessionCacheClient"/>
/// </summary>
/// <param name="client"></param>
/// <param name="maxCacheItems">The maximum number of sessions to keep in memory</param>
- protected SessionCacheClient(FBMClient client, int maxCacheItems)
+ protected SessionCacheClient(IRemoteCacheStore client, int maxCacheItems)
{
MaxLoadedEntires = maxCacheItems;
CacheLock = new();
CacheTable = new(maxCacheItems);
- Client = client;
+ Store = client;
}
private ulong _waitingCount;
@@ -202,12 +201,6 @@ namespace VNLib.Plugins.Sessions.Cache.Client
/// <returns></returns>
public async Task CleanupExpiredSessionsAsync(ILogProvider log, CancellationToken token)
{
- //Close handler
- void OnConnectionClosed(object? sender, EventArgs e) => CacheHardClear();
-
- //Attach event
- Client.ConnectionClosed += OnConnectionClosed;
-
while (true)
{
try
@@ -229,9 +222,6 @@ namespace VNLib.Plugins.Sessions.Cache.Client
log.Error(ex);
}
}
-
- //remove handler
- Client.ConnectionClosed -= OnConnectionClosed;
}
///<inheritdoc/>
diff --git a/Libs/VNLib.Plugins.Sessions.Cache.Client/VNLib.Plugins.Sessions.Cache.Client.csproj b/Libs/VNLib.Plugins.Sessions.Cache.Client/VNLib.Plugins.Sessions.Cache.Client.csproj
index a75ebe3..8271ed2 100644
--- a/Libs/VNLib.Plugins.Sessions.Cache.Client/VNLib.Plugins.Sessions.Cache.Client.csproj
+++ b/Libs/VNLib.Plugins.Sessions.Cache.Client/VNLib.Plugins.Sessions.Cache.Client.csproj
@@ -5,6 +5,8 @@
<Authors>Vaughn Nugent</Authors>
<Copyright>Copyright © 2022 Vaughn Nugent</Copyright>
<Version>1.0.1.1</Version>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\StrongNameingKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup>
@@ -38,7 +40,9 @@
<ItemGroup>
<ProjectReference Include="..\..\..\..\VNLib\Essentials\src\VNLib.Plugins.Essentials.csproj" />
- <ProjectReference Include="..\..\..\DataCaching\VNLib.Data.Caching\src\VNLib.Data.Caching.csproj" />
+ <ProjectReference Include="..\..\..\..\VNLib\Http\src\VNLib.Net.Http.csproj" />
+ <ProjectReference Include="..\..\..\..\VNLib\Utils\src\VNLib.Utils.csproj" />
+ <ProjectReference Include="..\..\..\DataCaching\VNLib.Data.Caching\VNLib.Data.Caching.csproj" />
</ItemGroup>
</Project>
diff --git a/Plugins/CacheBroker/CacheBroker.csproj b/Plugins/CacheBroker/CacheBroker.csproj
index f4ea139..1d4fdcc 100644
--- a/Plugins/CacheBroker/CacheBroker.csproj
+++ b/Plugins/CacheBroker/CacheBroker.csproj
@@ -6,6 +6,8 @@
<RootNamespace>VNLib.Plugins.Cache.Broker</RootNamespace>
<Authors>Vaughn Nugent</Authors>
<Version>1.0.1.2</Version>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\StrongNameingKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
diff --git a/Plugins/CacheBroker/Endpoints/BrokerRegistrationEndpoint.cs b/Plugins/CacheBroker/Endpoints/BrokerRegistrationEndpoint.cs
index be700d1..7867e97 100644
--- a/Plugins/CacheBroker/Endpoints/BrokerRegistrationEndpoint.cs
+++ b/Plugins/CacheBroker/Endpoints/BrokerRegistrationEndpoint.cs
@@ -33,9 +33,7 @@ using System.Threading;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Collections.Generic;
-using System.Security.Cryptography;
using System.Text.Json.Serialization;
-using System.Security.Cryptography.X509Certificates;
using RestSharp;
@@ -110,8 +108,7 @@ namespace VNLib.Plugins.Cache.Broker.Endpoints
private async Task<ReadOnlyJsonWebKey> GetClientPublic()
{
- using SecretResult secret = await this.GetPlugin().TryGetSecretAsync("client_public_key") ?? throw new InvalidOperationException("Client public key not found in vault");
- return secret.GetJsonWebKey();
+ return await this.GetPlugin().TryGetSecretAsync("client_public_key").ToJsonWebKey() ?? throw new InvalidOperationException("Client public key not found in vault");
}
private async Task<ReadOnlyJsonWebKey> GetCachePublic()
diff --git a/Plugins/SessionCacheServer/Endpoints/BrokerHeartBeat.cs b/Plugins/SessionCacheServer/Endpoints/BrokerHeartBeat.cs
index 2e380a3..bd1233e 100644
--- a/Plugins/SessionCacheServer/Endpoints/BrokerHeartBeat.cs
+++ b/Plugins/SessionCacheServer/Endpoints/BrokerHeartBeat.cs
@@ -37,7 +37,7 @@ using VNLib.Plugins.Extensions.Loading;
namespace VNLib.Plugins.Essentials.Sessions.Server.Endpoints
{
- internal class BrokerHeartBeat : ResourceEndpointBase
+ internal sealed class BrokerHeartBeat : ResourceEndpointBase
{
public override string Path => "/heartbeat";
@@ -64,9 +64,7 @@ namespace VNLib.Plugins.Essentials.Sessions.Server.Endpoints
private async Task<ReadOnlyJsonWebKey> GetBrokerPubAsync()
{
- using SecretResult brokerPubKey = await Pbase.TryGetSecretAsync("broker_public_key") ?? throw new KeyNotFoundException("Missing required secret : broker_public_key");
-
- return brokerPubKey.GetJsonWebKey();
+ return await Pbase.TryGetSecretAsync("broker_public_key").ToJsonWebKey() ?? throw new KeyNotFoundException("Missing required secret : broker_public_key");
}
protected override async ValueTask<VfReturnType> GetAsync(HttpEntity entity)
diff --git a/Plugins/SessionCacheServer/Endpoints/ConnectEndpoint.cs b/Plugins/SessionCacheServer/Endpoints/ConnectEndpoint.cs
index 77acb13..2fe0994 100644
--- a/Plugins/SessionCacheServer/Endpoints/ConnectEndpoint.cs
+++ b/Plugins/SessionCacheServer/Endpoints/ConnectEndpoint.cs
@@ -47,7 +47,7 @@ using VNLib.Plugins.Essentials.Extensions;
namespace VNLib.Plugins.Essentials.Sessions.Server.Endpoints
{
- class ConnectEndpoint : ResourceEndpointBase
+ internal sealed class ConnectEndpoint : ResourceEndpointBase
{
const int MAX_RECV_BUF_SIZE = 1000 * 1024;
const int MIN_RECV_BUF_SIZE = 8 * 1024;
@@ -194,21 +194,15 @@ namespace VNLib.Plugins.Essentials.Sessions.Server.Endpoints
private async Task<ReadOnlyJsonWebKey> GetClientPubAsync()
{
- using SecretResult brokerPubKey = await Pbase.TryGetSecretAsync("client_public_key") ?? throw new KeyNotFoundException("Missing required secret : client_public_key");
-
- return brokerPubKey.GetJsonWebKey();
+ return await Pbase.TryGetSecretAsync("client_public_key").ToJsonWebKey() ?? throw new KeyNotFoundException("Missing required secret : client_public_key");
}
private async Task<ReadOnlyJsonWebKey> GetCachePubAsync()
{
- using SecretResult cachPublic = await Pbase.TryGetSecretAsync("cache_public_key") ?? throw new KeyNotFoundException("Missing required secret : client_public_key");
-
- return cachPublic.GetJsonWebKey();
+ return await Pbase.TryGetSecretAsync("cache_public_key").ToJsonWebKey() ?? throw new KeyNotFoundException("Missing required secret : client_public_key");
}
private async Task<ReadOnlyJsonWebKey> GetCachePrivateKeyAsync()
{
- using SecretResult cachePrivate = await Pbase.TryGetSecretAsync("cache_private_key") ?? throw new KeyNotFoundException("Missing required secret : client_public_key");
-
- return cachePrivate.GetJsonWebKey();
+ return await Pbase.TryGetSecretAsync("cache_private_key").ToJsonWebKey() ?? throw new KeyNotFoundException("Missing required secret : client_public_key");
}
private async Task ChangeWorkerAsync(CancellationToken cancellation)
diff --git a/Plugins/SessionCacheServer/ObjectCacheServer.csproj b/Plugins/SessionCacheServer/ObjectCacheServer.csproj
index 2cf298d..ff239cc 100644
--- a/Plugins/SessionCacheServer/ObjectCacheServer.csproj
+++ b/Plugins/SessionCacheServer/ObjectCacheServer.csproj
@@ -1,5 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
-
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
@@ -7,7 +6,8 @@
<Version>1.0.1.1</Version>
<RootNamespace>VNLib.Plugins.Essentials.Sessions.Server</RootNamespace>
<Copyright>Copyright © 2022 Vaughn Nugent</Copyright>
-
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\StrongNameingKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<!-- Resolve nuget dll files and store them in the output dir -->
@@ -52,7 +52,12 @@
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
- <Exec Command="start xcopy &quot;$(TargetDir)&quot; &quot;$(ProjectDir)/liveplugin/$(TargetName)&quot; /E /Y /R&#xD;&#xA;start xcopy &quot;$(TargetDir)&quot; &quot;\\vaughnnugent.com\Internal\Vaughns Folder\Programming\LiveWebPlugins\SessionServerPlugins/$(TargetName)&quot; /E /Y /R" />
+
+ <Exec Command="erase &quot;\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\VNLib\Web Plugins/$(TargetName)&quot; /q &gt; nul&#xD;&#xA;start xcopy &quot;$(TargetDir)&quot; &quot;$(ProjectDir)/liveplugin/$(TargetName)&quot; /E /Y /R&#xD;&#xA;start xcopy &quot;$(TargetDir)&quot; &quot;\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\VNLib\Web Plugins/$(TargetName)&quot; /E /Y /R" />
+ </Target>
+
+ <Target Name="PostBuild" AfterTargets="PostBuildEvent">
+ <Exec Command="erase &quot;F:\Programming\Web Plugins\DevPlugins\$(TargetName)&quot; /q &gt; nul" />
</Target>
</Project>
diff --git a/Plugins/SessionCacheServer/ObjectCacheServerEntry.cs b/Plugins/SessionCacheServer/ObjectCacheServerEntry.cs
index 20a6268..85a7996 100644
--- a/Plugins/SessionCacheServer/ObjectCacheServerEntry.cs
+++ b/Plugins/SessionCacheServer/ObjectCacheServerEntry.cs
@@ -287,14 +287,12 @@ namespace VNLib.Plugins.Essentials.Sessions.Server
private async Task<ReadOnlyJsonWebKey> GetCachePrivate()
{
- using SecretResult secret = await this.TryGetSecretAsync("cache_private_key") ?? throw new KeyNotFoundException("Failed to load the cache private key");
- return secret.GetJsonWebKey();
+ return await this.TryGetSecretAsync("cache_private_key").ToJsonWebKey() ?? throw new KeyNotFoundException("Failed to load the cache private key");
}
private async Task<ReadOnlyJsonWebKey> GetBrokerPublic()
{
- using SecretResult secret = await this.TryGetSecretAsync("broker_public_key") ?? throw new KeyNotFoundException("Failed to load the broker's public key");
- return secret.GetJsonWebKey();
+ return await this.TryGetSecretAsync("broker_public_key").ToJsonWebKey() ?? throw new KeyNotFoundException("Failed to load the broker's public key");
}
diff --git a/Plugins/SessionProvider/GlobalCache.cs b/Plugins/SessionProvider/GlobalCache.cs
deleted file mode 100644
index 2f64632..0000000
--- a/Plugins/SessionProvider/GlobalCache.cs
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-* Copyright (c) 2022 Vaughn Nugent
-*
-* Library: VNLib
-* Package: SessionProvider
-* File: GlobalCache.cs
-*
-* GlobalCache.cs is part of SessionProvider which is part of the larger
-* VNLib collection of libraries and utilities.
-*
-* SessionProvider 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.
-*
-* SessionProvider 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.Threading;
-using System.Threading.Tasks;
-
-//using VNLib.Data.Caching;
-//using VNLib.Net.Messaging.FBM.Client;
-//using VNLib.Net.Messaging.FBM.Client.Exceptions;
-
-
-namespace VNLib.Plugins.Essentials.Sessions
-{
- /*internal class GlobalCache : IGlobalCacheProvider
- {
- private readonly FBMClient Client;
- private readonly TimeSpan OperationTimeout;
-
- public GlobalCache(FBMClient cacheProvider, TimeSpan cancellation)
- {
- this.Client = cacheProvider;
- this.OperationTimeout = cancellation;
- }
-
- //If the wait handle will block, the client is connected
- bool IGlobalCacheProvider.IsConnected => !Client.ConnectionStatusHandle.WaitOne(0);
-
- async Task IGlobalCacheProvider.DeleteAsync(string key)
- {
- if (OperationTimeout > TimeSpan.Zero && OperationTimeout < TimeSpan.MaxValue)
- {
- CancellationTokenSource cts = new(OperationTimeout);
- try
- {
- //Delete value
- await Client.DeleteObjectAsync(key, cts.Token);
- }
- catch (FBMException fbm)
- {
- //Catch fbm excpetions and wrap them in global cache exception
- throw new GlobalCacheException("Failed to delete cache record, see inner exception", fbm);
- }
- catch (OperationCanceledException)
- {
- throw new TimeoutException("The operation has been cancelled, due to a timeout");
- }
- finally
- {
- cts.Dispose();
- }
- }
- else
- {
- try
- {
- //Delete value
- await Client.DeleteObjectAsync(key);
- }
- catch (FBMException fbm)
- {
- //Catch fbm excpetions and wrap them in global cache exception
- throw new GlobalCacheException("Failed to delete cache record, see inner exception", fbm);
- }
- }
- }
-
- async Task<T> IGlobalCacheProvider.GetAsync<T>(string key)
- {
- if (OperationTimeout > TimeSpan.Zero && OperationTimeout < TimeSpan.MaxValue)
- {
- CancellationTokenSource cts = new(OperationTimeout);
- try
- {
- //Try to get the value
- return await Client.GetObjectAsync<T>(key, cts.Token);
- }
- catch (FBMException fbm)
- {
- //Catch fbm excpetions and wrap them in global cache exception
- throw new GlobalCacheException("Failed to delete cache record, see inner exception", fbm);
- }
- catch (OperationCanceledException)
- {
- throw new TimeoutException("The operation has been cancelled, due to a timeout");
- }
- finally
- {
- cts.Dispose();
- }
- }
- else
- {
- try
- {
- //Try to get the value
- return await Client.GetObjectAsync<T>(key);
- }
- catch (FBMException fbm)
- {
- //Catch fbm excpetions and wrap them in global cache exception
- throw new GlobalCacheException("Failed to delete cache record, see inner exception", fbm);
- }
- }
- }
-
- async Task IGlobalCacheProvider.SetAsync<T>(string key, T value)
- {
- if (OperationTimeout > TimeSpan.Zero && OperationTimeout < TimeSpan.MaxValue)
- {
- CancellationTokenSource cts = new(OperationTimeout);
- try
- {
- await Client.AddOrUpdateObjectAsync(key, null, value, cts.Token);
- }
- catch (FBMException fbm)
- {
- //Catch fbm excpetions and wrap them in global cache exception
- throw new GlobalCacheException("Failed to delete cache record, see inner exception", fbm);
- }
- catch (OperationCanceledException)
- {
- throw new TimeoutException("The operation has been cancelled, due to a timeout");
- }
- finally
- {
- cts.Dispose();
- }
- }
- else
- {
- try
- {
- await Client.AddOrUpdateObjectAsync(key, null, value);
- }
- catch (FBMException fbm)
- {
- //Catch fbm excpetions and wrap them in global cache exception
- throw new GlobalCacheException("Failed to delete cache record, see inner exception", fbm);
- }
- }
- }
- }*/
-}
diff --git a/Plugins/SessionProvider/SessionProvider.csproj b/Plugins/SessionProvider/SessionProvider.csproj
index 98fb5da..6401cb9 100644
--- a/Plugins/SessionProvider/SessionProvider.csproj
+++ b/Plugins/SessionProvider/SessionProvider.csproj
@@ -11,6 +11,8 @@
<Copyright>Copyright © 2022 Vaughn Nugent</Copyright>
<Version>1.0.3.1</Version>
<PackageProjectUrl>https://www.vaughnnugent.com/resources</PackageProjectUrl>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\StrongNameingKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>