diff options
Diffstat (limited to 'libs/VNLib.Plugins.Sessions.Cache.Client/src')
-rw-r--r-- | libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs | 92 | ||||
-rw-r--r-- | libs/VNLib.Plugins.Sessions.Cache.Client/src/VNLib.Plugins.Sessions.Cache.Client.csproj | 21 |
2 files changed, 77 insertions, 36 deletions
diff --git a/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs b/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs index 32dcc34..18ea99e 100644 --- a/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs +++ b/libs/VNLib.Plugins.Sessions.Cache.Client/src/SessionSerializer.cs @@ -55,13 +55,13 @@ namespace VNLib.Plugins.Sessions.Cache.Client */ private readonly Dictionary<string, WaitEntry> _waitTable; - + /// <summary> /// Initializes a new <see cref="SessionSerializer{TSession}"/> /// </summary> /// <param name="poolCapacity">The maximum number of wait entry instances to hold in memory cache</param> - public SessionSerializer(int poolCapacity):base(poolCapacity, 0, null) + public SessionSerializer(int poolCapacity) : base(poolCapacity, 0, null) { //Session-ids are security senstive, we must use ordinal(binary) string comparison _waitTable = new Dictionary<string, WaitEntry>(poolCapacity, StringComparer.Ordinal); @@ -86,23 +86,48 @@ namespace VNLib.Plugins.Sessions.Cache.Client cancellation.ThrowIfCancellationRequested(); WaitEnterToken token; + WaitEntry? wait; - lock (StoreLock) + if (cancellation.CanBeCanceled) { - //See if the entry already exists, otherwise get a new wait entry - if (!_waitTable.TryGetValue(moniker.SessionID, out WaitEntry? wait)) + lock (StoreLock) { - GetWaitEntry(ref wait, moniker); + //See if the entry already exists, otherwise get a new wait entry + if (!_waitTable.TryGetValue(moniker.SessionID, out wait)) + { + GetWaitEntry(ref wait, moniker); - //Add entry to store - _waitTable[moniker.SessionID] = wait; + //Add entry to store + _waitTable[moniker.SessionID] = wait; + } + + //Get waiter before leaving lock + wait.ScheduleWait(cancellation, out token); } - //Get waiter before leaving lock - wait.GetWaiter(out token); + //Enter wait and setup cancellation continuation + return EnterCancellableWait(in token, wait); } + else + { + lock (StoreLock) + { + //See if the entry already exists, otherwise get a new wait entry + if (!WaitTable.TryGetValue(moniker, out wait)) + { + GetWaitEntry(ref wait, moniker); + + //Add entry to store + WaitTable[moniker] = wait; + } + + //Get waiter before leaving lock + wait.ScheduleWait(out token); + } - return token.EnterWaitAsync(cancellation); + //Enter the waiter without any cancellation support + return token.EnterWaitAsync(); + } } ///<inheritdoc/> @@ -110,31 +135,32 @@ namespace VNLib.Plugins.Sessions.Cache.Client { WaitReleaseToken releaser; - lock (StoreLock) + do { - WaitEntry entry = _waitTable[moniker.SessionID]; - - //Call release while holding store lock - if(entry.Release(out releaser) == 0) + lock (StoreLock) { - //No more waiters - _waitTable.Remove(moniker.SessionID); - - /* - * We must release the semaphore before returning to pool, - * its safe because there are no more waiters - */ - releaser.Release(); - - ReturnEntry(entry); - - //already released - releaser = default; - } - } + WaitEntry entry = _waitTable[moniker.SessionID]; - //Release sem outside of lock - releaser.Release(); + //Call release while holding store lock + if (entry.ExitWait(out releaser) == 0) + { + //No more waiters + _waitTable.Remove(moniker.SessionID); + + /* + * We must release the semaphore before returning to pool, + * its safe because there are no more waiters + */ + releaser.Release(); + + ReturnEntry(entry); + + //already released + releaser = default; + } + } + //See base class for why we need to loop + } while (!releaser.Release()); } ///<inheritdoc/> diff --git a/libs/VNLib.Plugins.Sessions.Cache.Client/src/VNLib.Plugins.Sessions.Cache.Client.csproj b/libs/VNLib.Plugins.Sessions.Cache.Client/src/VNLib.Plugins.Sessions.Cache.Client.csproj index 0162020..51e6d5c 100644 --- a/libs/VNLib.Plugins.Sessions.Cache.Client/src/VNLib.Plugins.Sessions.Cache.Client.csproj +++ b/libs/VNLib.Plugins.Sessions.Cache.Client/src/VNLib.Plugins.Sessions.Cache.Client.csproj @@ -16,14 +16,29 @@ <Authors>Vaughn Nugent</Authors> <Company>Vaughn Nugent</Company> <Product>Cache backed session client library</Product> - <Description> - Boilerplate and abstractions library for implementing cache backed HTTP sessions. - </Description> + <Description>Boilerplate and abstractions library for implementing cache backed HTTP sessions.</Description> <Copyright>Copyright © 2023 Vaughn Nugent</Copyright> <PackageProjectUrl>https://www.vaughnnugent.com/resources/software/modules/VNLib.Plugins.Sessions</PackageProjectUrl> <RepositoryUrl>https://github.com/VnUgE/VNLib.Plugins.Sessions/tree/master/libs/VNLib.Plugins.Sessions.Cache.Client</RepositoryUrl> </PropertyGroup> + <PropertyGroup> + <PackageReadmeFile>README.md</PackageReadmeFile> + <PackageLicenseFile>LICENSE</PackageLicenseFile> + <PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance> + </PropertyGroup> + <ItemGroup> + <None Include="..\..\..\LICENSE"> + <Pack>True</Pack> + <PackagePath>\</PackagePath> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="..\README.md"> + <Pack>True</Pack> + <PackagePath>\</PackagePath> + </None> + </ItemGroup> + <ItemGroup> <PackageReference Include="ErrorProne.NET.CoreAnalyzers" Version="0.1.2"> <PrivateAssets>all</PrivateAssets> |