using Elsa.Caching; using Elsa.Caching.Models; using Elsa.Caching.UnitTests; using Microsoft.Extensions.DependencyInjection; if (args.Length != 3) throw new ArgumentException("Usage: 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(); 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("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("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"); }