Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/ActionCache.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.46.1" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="$(_TargetVersion)" />
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="$(_TargetVersion)" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
Expand Down
78 changes: 0 additions & 78 deletions src/Common/Concurrency/DistributedCacheLocker.cs

This file was deleted.

45 changes: 0 additions & 45 deletions src/Common/Concurrency/Locks/DistributedCacheLock.cs

This file was deleted.

1 change: 1 addition & 0 deletions src/Common/Concurrency/Locks/NullCacheLock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ public class NullCacheLock : CacheLock
/// <param name="resource">The resource name associated with this lock.</param>
public NullCacheLock(string resource) : base(resource)
{
IsAcquired = true;
}
}
20 changes: 0 additions & 20 deletions src/Common/Concurrency/Locks/SemaphoreSlimLock.cs

This file was deleted.

51 changes: 0 additions & 51 deletions src/Common/Concurrency/SemaphoreSlimLocker.cs

This file was deleted.

2 changes: 1 addition & 1 deletion src/Memory/Extensions/Internal/IMemoryCacheExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ internal static void SetKey(this IMemoryCache cache, Namespace @namespace, strin
var keys = cache.GetKeys(@namespace, entryOptions);
if (keys.TryAdd(key, entryOptions.AbsoluteExpiration))
{
cache.Set(key, keys, entryOptions);
cache.Set(@namespace, keys, entryOptions);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Memory/MemoryActionCache.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using ActionCache.Common.Caching;
using ActionCache.Common.Concurrency;
using ActionCache.Common.Concurrency.Locks;
using ActionCache.Memory.Extensions.Internal;
using ActionCache.Utilities;
using Microsoft.Extensions.Caching.Memory;
Expand All @@ -10,7 +10,7 @@
/// <summary>
/// Represents a memory action cache implementation.
/// </summary>
public class MemoryActionCache : ActionCacheBase<SemaphoreSlimLock>
public class MemoryActionCache : ActionCacheBase<NullCacheLock>
{
/// <summary>
/// A memory cache implementation.
Expand All @@ -31,7 +31,7 @@
public MemoryActionCache(
IMemoryCache cache,
CancellationTokenSource cancellationTokenSource,
ActionCacheContext<SemaphoreSlimLock> context
ActionCacheContext<NullCacheLock> context
) : base(context)
{
Cache = cache;
Expand All @@ -55,15 +55,15 @@
/// </summary>
/// <param name="key">The key of the cache entry.</param>
/// <returns>The cached value or null if not found.</returns>
public override Task<TValue> GetAsync<TValue>(string key) =>

Check warning on line 58 in src/Memory/MemoryActionCache.cs

View workflow job for this annotation

GitHub Actions / Unit Tests

Nullability of reference types in return type doesn't match overridden member.

Check warning on line 58 in src/Memory/MemoryActionCache.cs

View workflow job for this annotation

GitHub Actions / Integration Tests

Nullability of reference types in return type doesn't match overridden member.

Check warning on line 58 in src/Memory/MemoryActionCache.cs

View workflow job for this annotation

GitHub Actions / Analyze (C#)

Nullability of reference types in return type doesn't match overridden member.
Task.FromResult(Cache.Get<TValue>(Namespace.Create(key)));

Check warning on line 59 in src/Memory/MemoryActionCache.cs

View workflow job for this annotation

GitHub Actions / Unit Tests

Nullability of reference types in value of type 'Task<TValue?>' doesn't match target type 'Task<TValue>'.

Check warning on line 59 in src/Memory/MemoryActionCache.cs

View workflow job for this annotation

GitHub Actions / Integration Tests

Nullability of reference types in value of type 'Task<TValue?>' doesn't match target type 'Task<TValue>'.

/// <summary>
/// Asynchronously sets a value in the cache.
/// </summary>
/// <param name="key">The cache key to set the value for.</param>
/// <param name="value">The value to set in the cache.</param>
public override Task SetAsync<TValue>(string key, TValue value)

Check warning on line 66 in src/Memory/MemoryActionCache.cs

View workflow job for this annotation

GitHub Actions / Unit Tests

Nullability of type of parameter 'value' doesn't match overridden member (possibly because of nullability attributes).

Check warning on line 66 in src/Memory/MemoryActionCache.cs

View workflow job for this annotation

GitHub Actions / Integration Tests

Nullability of type of parameter 'value' doesn't match overridden member (possibly because of nullability attributes).

Check warning on line 66 in src/Memory/MemoryActionCache.cs

View workflow job for this annotation

GitHub Actions / Analyze (C#)

Nullability of type of parameter 'value' doesn't match overridden member (possibly because of nullability attributes).
{
var entryOptions = CreateEntryOptions();
Cache.Set(Namespace.Create(key), value, entryOptions);
Expand Down
15 changes: 5 additions & 10 deletions src/Memory/MemoryActionCacheFactory.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using ActionCache.Common;
using ActionCache.Common.Caching;
using ActionCache.Common.Concurrency;
using ActionCache.Common.Concurrency.Locks;
using ActionCache.Utilities;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
Expand Down Expand Up @@ -45,15 +46,12 @@ IActionCacheRefreshProvider refreshProvider
{
if (ExpirationTokens.TryGetOrAdd(@namespace, out var expirationTokenSource))
{
var context = new ActionCacheContext<SemaphoreSlimLock>
var context = new ActionCacheContext<NullCacheLock>
{
Namespace = @namespace,
EntryOptions = EntryOptions,
RefreshProvider = RefreshProvider,
CacheLocker = new SemaphoreSlimLocker(
EntryOptions.LockDuration,
EntryOptions.LockTimeout
)
CacheLocker = new NullCacheLocker()
};

return new MemoryActionCache(Cache, expirationTokenSource, context);
Expand All @@ -69,7 +67,7 @@ IActionCacheRefreshProvider refreshProvider
{
if (ExpirationTokens.TryGetOrAdd(@namespace, out var expirationTokenSource))
{
var context = new ActionCacheContext<SemaphoreSlimLock>
var context = new ActionCacheContext<NullCacheLock>
{
Namespace = @namespace,
EntryOptions = new ActionCacheEntryOptions
Expand All @@ -78,10 +76,7 @@ IActionCacheRefreshProvider refreshProvider
SlidingExpiration = slidingExpiration
},
RefreshProvider = RefreshProvider,
CacheLocker = new SemaphoreSlimLocker(
EntryOptions.LockDuration,
EntryOptions.LockTimeout
)
CacheLocker = new NullCacheLocker()
};

return new MemoryActionCache(Cache, expirationTokenSource, context);
Expand Down
31 changes: 31 additions & 0 deletions src/Redis/Concurrency/Locks/RedisCacheLock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using ActionCache.Common.Concurrency;

namespace ActionCache.Redis.Concurrency.Locks;

/// <summary>
/// Represents a Redis-backed distributed lock acquired via SET NX PX.
/// Holds the lock key and a unique fencing token used by the release script
/// to ensure only the owner can release the lock.
/// </summary>
public class RedisCacheLock : CacheLock
{
/// <summary>
/// Initializes a new instance of the <see cref="RedisCacheLock"/> class.
/// </summary>
/// <param name="resource">The logical resource being locked (used to build <see cref="Key"/>).</param>
/// <param name="lockDuration">How long the lock is held in Redis (TTL on the key).</param>
/// <param name="lockTimeout">Maximum time the locker will poll before giving up.</param>
public RedisCacheLock(string resource, TimeSpan lockDuration, TimeSpan lockTimeout) : base(resource)
{
Duration = lockDuration;
Timeout = lockTimeout;
Key = $"Lock:{resource}";
Token = Guid.NewGuid().ToString("N");
}

/// <summary>Redis key under which the lock is stored.</summary>
public string Key { get; }

/// <summary>Unique fencing token stored as the Redis value; used by the release script.</summary>
public string Token { get; }
}
Loading
Loading