using System.Collections.Concurrent;
namespace w4c_workflows.Services;
///
/// In-memory lease service for lite/self-hosted mode where Redis is not available.
/// Uses a ConcurrentDictionary with TTL tracking. Not distributed — only works
/// for a single-process deployment (which is the lite mode use case).
///
public sealed class InMemoryLeaseService : ILeaseService
{
private record Lease(string Owner, DateTime ExpiresAt);
private readonly ConcurrentDictionary _leases = new();
public Task AcquireAsync(string tenantId, string runId, string owner, TimeSpan ttl)
{
var key = $"{tenantId}:{runId}";
var lease = new Lease(owner, DateTime.UtcNow + ttl);
return Task.FromResult(_leases.TryAdd(key, lease));
}
public Task RenewAsync(string tenantId, string runId, string owner, TimeSpan ttl)
{
var key = $"{tenantId}:{runId}";
if (!_leases.TryGetValue(key, out var current) || current.Owner != owner)
return Task.FromResult(false);
_leases[key] = new Lease(owner, DateTime.UtcNow + ttl);
return Task.FromResult(true);
}
public Task ReleaseAsync(string tenantId, string runId, string owner)
{
var key = $"{tenantId}:{runId}";
// Remove only if the owner still matches (compare-and-delete).
return Task.FromResult(_leases.TryRemove(key, out var lease) && lease.Owner == owner);
}
}