using System; using Enyim.Caching; using Enyim.Caching.Memcached; using Microsoft.Extensions.Logging; namespace Expedience.Infrastructure.Concurrency { public interface IDistributedLock { bool AcquireLock(string lockKey, TimeSpan timeout, TimeSpan lockExpiration); void ReleaseLock(string lockKey); } public class DistributedLock : IDistributedLock { private readonly IMemcachedClient _memcachedClient; public DistributedLock(ILogger logger, IMemcachedClient memcachedClient) { _memcachedClient = memcachedClient; } public bool AcquireLock(string lockKey, TimeSpan timeout, TimeSpan lockExpiration) { var startTime = DateTime.UtcNow; while (true) { if (_memcachedClient.Store(StoreMode.Add, lockKey, true, lockExpiration)) { return true; // Lock acquired } if (DateTime.UtcNow - startTime > timeout) { return false; // Timeout } Thread.Sleep(100); // Wait and try again } } public void ReleaseLock(string lockKey) { _memcachedClient.Remove(lockKey); } } }