configure Redis cache and distributed locks

This commit is contained in:
Behzad Alizadeh
2026-10-10 16:50:37 +03:30
parent 3f75fec42b
commit 2676bf6ffd
155 changed files with 1784 additions and 229 deletions
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup><OutputType>Exe</OutputType><IsTestProject>false</IsTestProject></PropertyGroup>
<ItemGroup>
<ProjectReference Include="../../../src/modules/Elsa.Caching.Redis/Elsa.Caching.Redis.csproj" />
<ProjectReference Include="../../../src/modules/Elsa.EntityFrameworkCore/Elsa.EntityFrameworkCore.csproj" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" />
<Compile Include="../../unit/Elsa.Caching.UnitTests/CacheTestHost.cs" Link="CacheTestHost.cs" />
</ItemGroup>
</Project>
@@ -0,0 +1,41 @@
using Elsa.Caching;
using Elsa.Caching.Models;
using Elsa.Caching.UnitTests;
using Microsoft.Extensions.DependencyInjection;
if (args.Length != 3) throw new ArgumentException("Usage: <database path> <prefix> write|read|invalidate|read-updated|pending|bypass");
using var host = CacheTestHost.Create(args[0], true, args[1]);
await CacheTestHost.EnsureCreatedAsync(host);
var cache = host.GetRequiredService<ICacheManager>();
var options = new CacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(2) };
switch (args[2])
{
case "write":
Console.WriteLine(await cache.GetOrCreateAsync("definition", () => Task.FromResult("from-first-process"), options));
break;
case "read":
var value = await cache.GetOrCreateAsync<string>("definition", () => throw new Exception("Second process did not share Redis"), options);
if (value != "from-first-process") throw new Exception("Unexpected cache payload");
Console.WriteLine("PASS: payload shared across independent processes");
break;
case "invalidate":
var mutation = await cache.BeginMutationAsync();
await cache.CompleteMutationAsync(mutation);
Console.WriteLine(await cache.GetOrCreateAsync("definition", () => Task.FromResult("updated"), options));
break;
case "pending":
await cache.BeginMutationAsync();
Console.WriteLine("Pending durable fence recorded; process exiting");
break;
case "read-updated":
var updated = await cache.GetOrCreateAsync<string>("definition", () => throw new Exception("Updated payload was not shared"), options);
if (updated != "updated") throw new Exception("Old payload survived another process's mutation");
Console.WriteLine("PASS: another process observes the updated revision");
break;
case "bypass":
var fresh = await cache.GetOrCreateAsync("definition", () => Task.FromResult("sql-current"), options);
if (fresh != "sql-current") throw new Exception("Stale Redis payload was used after an unfinished mutation");
Console.WriteLine("PASS: unfinished mutation forces SQL reads after process restart");
break;
default: throw new ArgumentException("Unknown mode");
}